繁体   English   中英

如何使用 MongoDB C# 驱动程序投影查询嵌套列表

[英]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()内的IncludeExclude ,但也无济于事。 任何人都可以发光吗?

编辑:我的问题实际上与这个问题非常相似,但使用的是 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 来看,它应该是一个文档列表( TeamDataPlayers ),因此驱动程序无法执行此操作。 由于他无法将 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM