我们可以使用 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() 并将在修复驱动程序时进行更新。
假设我们在 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() 并将在修复驱动程序时进行更新。