我必须从数据库中的每个文档中获取一些次要数据,但我仍然希望减少流量以防止“表扫描”(只是术语,我知道它不是表格).
我有一个集合让我们说“书籍”(只是因为每个人都用它来举例),现在,我的问题是我只想要与给定作者的书籍标题.
var filter = Builders<Book>.Filter.Eq(n => n.Author,AuthorId); List<string> books = new List<string>(); using (var cursor = await BooksCollection.FindAsync(filter)) { while (await cursor.MoveNextAsync()) { var batch = cursor.Current; foreach (Book b in batch) books.Add(b.Title); } }
但是,当我扫描整个收集结果时,我正在使用大块数据,不是吗?让我们假设那些不是书籍而是整个网格网络,每个文档大约5-10 MB,我有成千上万的..我可以在这里减少流量,而不需要在另一个集合中存储我需要的数据吗?
解决方法
您可以通过
projection减少返回文档的大小,您可以在FindAsync的FindOptions参数中设置它,只包含您需要的字段:
var filter = Builders<Book>.Filter.Eq(n => n.Author,AuthorId); // Just project the Title and Author properties of each Book document var projection = Builders<Book>.Projection .Include(b => b.Title) .Include(b => b.Author) .Exclude("_id"); // _id is special and needs to be explicitly excluded if not needed var options = new FindOptions<Book,BsonDocument> { Projection = projection }; List<string> books = new List<string>(); using (var cursor = await BooksCollection.FindAsync(filter,options)) { while (await cursor.MoveNextAsync()) { var batch = cursor.Current; foreach (BsonDocument b in batch) // Get the string value of the Title field of the BsonDocument books.Add(b["Title"].AsString); } }
请注意,返回的文档是BsonDocument对象而不是Book对象,因为它们只包含投影字段.