我们有一个集合包含服务器中的文档。每个文件都像:
{ _id: "...", Prop1: "", Prop2: "", Prop3: "", LargeField: "", ... }
还有很多其他领域,但客户并不要求这些领域。
我想将文档加载为MyDoc
类,其定义为:
public class MyDoc {
public string Id { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
public string LargeField { get; set; }
}
我试过了:
var client = new MongoClient(uri);
var database = client.GetDatabase("MyDatabase");
var collection = database.GetCollection<MyDocs>("MyDocs");
var allDocs = collection.Find().ToList();
然后它将加载每个文档的所有字段,因此我必须将[BsonIgnoreExtraElements]
放在MyDoc
上。这里的问题是文档很大但我只需要一个限制的字段子集。是否可以让司机知道我只需要在班级中定义的字段?
如果没有,是否可以排除LargeField
之类的某些字段以使结果集更小?我试过了:
var fieldsBuilder = Builders<MyDoc>.Projection;
var fields = fieldsBuilder.Exclude(d => d.LargeField);
var allDocs = collection.Find().Project(fields).ToList();
但现在allDocs
变为BsonDocument
列表而不是MyDoc
列表。如何使用投影查询MyDoc
?
有人可以帮忙吗?它在传统MongoDB驱动程序中相当简单,但我不知道如何在新驱动程序中执行此操作。感谢。
答案 0 :(得分:4)
我遇到了类似的问题,我认为你需要指定泛型类型,出于某种原因,Project会自动采用BsonDocument。这应该将它从BsonDocument修复到你的类。
变化:
var allDocs = collection.Find().Project(fields).ToList();
要:
var allDocs = collection.Find<MyDoc>().Project<MyDoc>(fields).ToList();
至于如何仅包含某些字段,这可以像使用构建器(使用Include)或使用json形式的字符串一样完成,如:
var allDocs = collection.Find<MyDoc>().Project<MyDoc>("{Prop1: 1, Prop2: 1}").ToList();
我强烈建议您查看此帖子的投影: https://www.codementor.io/pmbanugo/working-with-mongodb-in-net-part-3-skip-sort-limit-and-projections-oqfwncyka
从这篇文章:
这带来了另一个区别:使用投影定义,它隐式地将文档类型从Student转换为BsonDocument,所以我们得到的是一个流畅的对象,结果将是一个BsonDocument(即使我们'重新使用是学生类型)。如果我们想与学生合作,我们必须表明我们仍然希望将该类型保留给学生。
答案 1 :(得分:1)
更新的方式:
var fieldsBuilder = Builders<MyDoc>.Projection;
var fields = fieldsBuilder.Exclude(d => d.BigField1).Exclude(d => d.BigField2);
return Collection.Find(x => x.id.Equals(id)).Project<MyDoc>(fields).ToEnumerable();
吉娜
答案 2 :(得分:0)
我们也可以使用 FindAsync
。要在 FindSync
中使用投影,我们必须像这样传递 FindOptions
:它将选择国家/地区名称、ID 和人口。
FindAsync
以异步方式从 DB 游标中逐个加载文档,当您拥有庞大的数据库时,这是一个不错的选择。
相关代码:
cursor = await collection.FindAsync(y => y.CountryID > 205,
new FindOptions<MyDoc, MyDoc>()
{
BatchSize = 20,
NoCursorTimeout = true,
AllowPartialResults = true,
Projection = "{'_id':1,'Name':1,'Population':1}"
}).ConfigureAwait(false);