使用MongoDB C#驱动程序2.4在查询中包含/排除字段

时间:2017-03-20 15:47:05

标签: mongodb-.net-driver

我们有一个集合包含服务器中的文档。每个文件都像:

{ _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驱动程序中相当简单,但我不知道如何在新驱动程序中执行此操作。感谢。

3 个答案:

答案 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);