【问题标题】:How do I return a document with filtered sub-documents using Mongo.Driver.Linq with the Mongo C# driver 2.3?如何使用带有 Mongo C# 驱动程序 2.3 的 Mongodb.Driver.Linq 返回带有过滤子文档的文档?
【发布时间】:2017-01-12 20:47:08
【问题描述】:

鉴于以下情况,我如何返回包含具有 TypeOfBar == "Big" 并且 的所有 Foos 具有 Foos 的 Bars 仅限于那些具有 TypeOfBar == " 的 Bars大”?

public class Foo
{
    public string _id { get; set; }
    public List<Bar> Bars { get; set; }
}

public class Bar
{
    public string _id { get; set; }
    public string TypeOfBar { get; set; }
}

我可以轻松获得第一部分(所有带有特定类型条的 Foos):

var client = new MongoClient("myconnectionstring");
var db = client.GetDatabase("myDb");
var collection = db.GetCollection<Foo>("Foos");

var foos = collection.AsQueryable().Where(x => x.Bars.Any(b => b.TypeOfBar == "Big"));

但是,我很难弄清楚如何让 db 也返回带有过滤的 Bars 列表的 Foos。

【问题讨论】:

    标签: c# mongodb linq mongodb-.net-driver


    【解决方案1】:

    如果您只想过滤掉“Big”类型的 Foo,您应该应用 ElemMatch Projection:

    var res = collection.Find(x => x.Bars.Any(b => b.TypeOfBar == "Big"))
        .Project(Builders<Foo>.Projection.ElemMatch(x=>x.Bars, b=>b.TypeOfBar == "Big"));
    

    您将遇到的问题:Projection 将返回 BSon。也许这就是你所需要的,你可以忍受它,如果没有,你应该将 Bson 反序列化到你的 Foo 类。我的完整查询看起来像:

    var res = collection.Find(x => x.Bars.Any(b => b.TypeOfBar == "Big"))
        .Project(Builders<Foo>.Projection.ElemMatch(x=>x.Bars, b=>b.TypeOfBar == "Big"))
        .ToEnumerable()
        .Select(b=>BsonSerializer.Deserialize<Foo>(b))
        .ToList();
    

    【讨论】:

    • 我认为您误解了我的要求。是的,您的两个示例都返回具有 TypeOfBar == "Big" 的 Bars 的 Foos,但是,它们将返回的 Foos' Bars 过滤为仅具有 TypeOfBar == "Big" 的那些 Bars .
    • 所以这适用于上面的玩具案例,其中 Foo 只有一个 _id 和一个 Bars 列表,但如果 Foo 有一些额外的属性,那么上面的答案就不起作用......返回的 Foos只有 Bars 的列表,但没有填写其他属性。如何返回带有过滤的 Bars 列表的 Foos 以及 Foo 的其他属性?
    猜你喜欢
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    相关资源
    最近更新 更多