想象一下,在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中通常的方法是使用投影。它与JSON查询(如)完美配合find({}, {"Field1": 1, "Next1.Field2": 1, "Next1.Next2.Field3": 1})
。我们得到了完整的对象层次结构,但是缺少了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上开了一个案例,他们已经确认这是他们方面的错误,并在JIRA中引用了该错误
没有使用对象表达式的已知解决方法,因此我们目前正在使用Include(),并且将在修复驱动程序后进行更新。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句