我们可以使用 MongoDB c# 驱动程序在投影中使用多个嵌套级别吗?

Can we use multiple nested levels inside a projection with the MongoDB c# driver?

假设我们在 c#7、dotnet core 3.1 中有以下 类,对应于存储在 MongoDB 集合中的数据:

public class Level1
{
    public string Field1 {get; set;}
    public IEnumerable<Level2> Next1 {get; set;}
}

public class Level2
{
    public string Field2 {get; set;}
    public IEnumerable<Level3> Next2 {get; set;}
}

public class Level3
{
    public string Field3 {get; set;}
    public string Field4 {get; set;}
}

出于优化考虑,我们要检索Field3而不是Field4,以及Level1和Level2的所有数据。 (当然这是一种简化:在真实案例中有很多我们实际上想要忽略的数据)。

为此,Mongo中常用的方法是使用投影。它与 find({}, {"Field1": 1, "Next1.Field2": 1, "Next1.Next2.Field3": 1}) 等 JSON 查询完美配合。我们得到了完整的对象层次结构,但缺少 Field4,即正是我们想要的。

但是,当我尝试使用最新版本的官方驱动程序在 c# 中执行此操作时,我遇到了困难。我显然可以只使用原始 JSON 查询并且它会工作 - 但我会错过驱动程序管理映射的所有优点,例如重构后的字段名称。所以我们要用表达式。

我已经试过了:

var result = db.GetCollection<Level1>("mycollection")
    .Find("{}")
    .Project(Builders<Level1>.Projection.Expression(p => new Level1
    {
        Field1 = p.Field1,
        Next1 = p.Next1.Select(s => new Level2
        {
            Field2 = s.Field2,
            Next2 = s.Next2.Select(r => new Level3
            {
                Field3 = r.Field3,
            },
        },
    }));    

然而,这会产生以下意想不到的结果 JSON:

find({}
}, {
    "Field1": 1,
    "Next2.Field3": 1,
    "Next1.Next2": 1,
    "Next1.Field2": 1
})

当然,这意味着 Field4 未被过滤 - 投影只是错误的。貌似只在两层起作用,两层后就停止给projection子句加前缀

你知道是否有可能用一个表达式来做我想做的事?谢谢!

我们已经在 MongoDB 开立了一个案例,他们已经确认这是他们这边的一个错误,引用 on their JIRA

没有已知的使用对象表达式的解决方法,所以我们现在使用 Include() 并将在修复驱动程序时进行更新。