[英]How to query nested list with MongoDB C# Driver projections
假设我的 MongoDB 中有以下数据:
{
"_id": {
"$oid": "62baf9a2851424fdb8c226f8"
},
"Name": "Team A",
"TeamData": {
"Players": [
{
"FirstName": "First Name A",
"LastName": "Last Name A"
},
{
"FirstName": "First Name B",
"LastName": "Last Name B"
}
]
}
}
我只想查询LastName
。 FirstName
应该是null
。
查询投影如下所示,使用点表示法:
{
"TeamData.Players.LastName": 1
}
如何使用 C# 驱动程序的 LINQ 支持来做到这一点? 我能够接近下面的代码,但不完全。
public IEnumerable<TeamDto> GetTeam()
{
return _collection.Find(filter).Project(x => new TeamDto
{
Id = x.Id,
TeamData = new TeamDataDto
{
Players = x.TeamData.Select(y => new PlayerDto
{
LastName = y.LastName
})
}
});
}
结果是: Players 数组已填充,但null
。 我还尝试了.Project()
内的Include
和Exclude
,但也无济于事。 任何人都可以发光吗?
编辑:我的问题实际上与这个问题非常相似,但使用的是 LINQ。 我知道有一种方法可以在.Project
中添加点符号,但这也不是我想要的。 谢谢。
对我来说,这看起来像是一个错误(或至少有点出乎意料的行为)。 您的投影确实有效。 我已经将它简化为这种形式:
var result = coll.Find("{}")
.Project(x => x.TeamData.Players.Select(c => c.LastName))
.ToList();
这种情况下实际生成的请求是:
{
"find": "coll",
"filter": {},
"projection": {
"Players.LastName": 1,
"TeamData.Players": 1,
"_id": 0
}
}
有点意外的是,这个关卡投影包含"TeamData.Players": 1
导致使用FirstName
创建结果,即使我们没有配置它:
{
"TeamData": {
"Players": [{
"FirstName": "First Name A",
"LastName": "Last Name A"
}, {
"FirstName": "First Name B",
"LastName": "Last Name B"
}
]
}
}
您也可以通过以下方式在 shell 中检查它:
db.runCommand({ "find" : "coll", "filter" : { }, "projection" : { "Players.LastName" : 1, "TeamData.Players" : 1, "_id" : 0 } })
上述投影的问题很小,可以通过直接指定预期投影来解决:
var result = coll.Find("{}")
.Project("{ 'TeamData.Players.LastName': 1 }")
.ToList();
只生成简单的预期 MQL:
{ "find" : "coll", "filter" : { }, "projection" : { "TeamData.Players.LastName" : 1 } }
反过来,返回预期的文档:
{
"_id": ObjectId("62d94cdeed9104ede4a35d75"),
"TeamData": {
"Players": [{
"LastName": "Last Name A"
}, {
"LastName": "Last Name B"
}
]
}
}
但问题是当服务器返回文档时,驱动程序还应该将此文档反序列化为投影输出。 您通过 LINQ 表达式配置的预计输出是一个简单的IEnumerable<string>
,但从服务器 POV 来看,它应该是一个文档列表( TeamData
、 Players
),因此驱动程序无法执行此操作。 由于他无法将 TeamData 文档转换为字符串,因此它只返回null
。 您可以通过替换BsonDocument
上的集合泛型类型来查看实际返回的文档:
var coll = db.GetCollection<BsonDocument>("coll");
var result = coll.Find("{}")
.Project("{ 'TeamData.Players.LastName': 1 }")
.ToList();
所以问题是驱动程序端的服务器响应的反序列化是不正确的,这就是为什么你的结果项目是null
。 我建议在此处创建 JIRA 票证
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.