【问题标题】:MongoDB $elemMatch projection on Nested Arrays嵌套数组上的 MongoDB $elemMatch 投影
【发布时间】:2017-10-10 15:46:03
【问题描述】:

我有一个这样的集合(摘要)。

    {
    "id":"summaryid",
    "locations": [
        {
            "id": "loc1",
            "datacenters": [
                {
                    "id": "dc1.1",
                    "clusters": [
                        {
                            "id": "cl1.1",
                            "servers": [
                                {
                                    "id": "srvr1.1",
                                    "services": [
                                        {
                                            "id": "srvc1.1"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                },
                {
                    "id": "dc1.2",
                    "clusters": [
                        {
                            "id": "cl1.2",
                            "servers": [
                                {
                                    "id": "srvr1.2",
                                    "services": [
                                        {
                                            "id": "srvc1.2"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "id": "loc2",
            "datacenters": [
                {
                    "id": "dc2.1",
                    "clusters": [
                        {
                            "id": "cl2.1",
                            "servers": [
                                {
                                    "id": "srvr2.1",
                                    "services": [
                                        {
                                            "id": "srvc2.1"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                },
                {
                    "id": "dc2.2",
                    "clusters": [
                        {
                            "id": "cl2.2",
                            "servers": [
                                {
                                    "id": "srvr2.2",
                                    "services": [
                                        {
                                            "id": "srvc2.2"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }

            ]
        }
    ]
}

现在我只想要 id 为 dc1.1 的数据中心的集群。我想排除集群的服务器。

我已经尝试使用带有 $elemMatch 和投影的 find 查询,如下所示。

db.summary.find({}, {"locations": { $elemMatch: { "datacenters._id" : 
"dc1.1" } }, "locations.datacenters.clusters":0, 
"locations.datacenters.servers":0, "locations.datacentercount" : 0, 
"locations.clustercount" : 0, "locations.servercount" : 0}).pretty()

我仍然得到所有数据中心,而不是只有 1 个与 id 匹配。 我不确定我这样做是否正确。

谢谢!

【问题讨论】:

  • 你能发布你预期的 json 结果吗?你只希望 { "id": "dc1.1", "clusters": [ {"id": "cl1.1",} ] }
  • 您的$elemMatch 指令使用的是"datacenters._id",但正确的路径(基于您提供的示例文档)是"datacenters.id"
  • find 是查找文档,而不是文档的一部分。投影无条件适用于所有属性,在这里不是正确的工具。您需要使用聚合来检索子文档。
  • 谢谢亚历克斯。我尝试了聚合并得到了我想要的。以下是我正在使用的。 ` db.summary.aggregate([ {"$unwind": "$locations"}, {"$unwind": "$locations.datacenters"}, { $match: { "locations.datacenters._id" : "dc1. 1" } }, { $project : {"locations.datacenters.servers" : 0, "locations.datacenters.clusters.servers" : 0} } ]).pretty() `
  • 新的挑战是我正在使用 spring-mongodb-data 的 ProjectionOperation 和 mongoTemplate。我不断收到以下错误。 ProjectionOperation projectStage = new ProjectionOperation().andExclude("locations.datacenters.servers", "locations.datacenters.clusters.servers");Exclusion of field locations.datacenters.servers not allowed. Projections by the mongodb aggregation framework only support the exclusion of the _id field!

标签: mongodb mongodb-query


【解决方案1】:

$elemMatch 无法投影嵌套数组元素。

您可以在 3.4 服务器中尝试以下聚合。

使用$unwind 几次到达嵌套数组并应用$match 选择嵌套数组元素。

   db.summary.aggregate([
      {
        "$match": {
          "locations.datacenters._id": "dc1.1"
        }
      },
      {
        "$unwind": "$locations"
      },
      {
        "$unwind": "$locations.datacenters"
      },
      {
        "$match": {
          "locations.datacenters._id": "dc1.1"
        }
      },
      {
        "$project": {
          "locations.datacenters.clusters.servers": 0
        }
      }
    ])

{"$project": {"locations.datacenters.clusters.servers": 0}} 将删除 servers 字段,同时将所有其他字段保留在最终输出中。

来自文档

如果指定排除 _id 以外的字段,则不能 采用任何其他 $project 规范形式:即,如果您排除 字段,您也不能指定包含字段,重置 现有字段的值,或添加新字段。

参考: https://docs.mongodb.com/manual/reference/operator/aggregation/project/#exclude-fields

【讨论】:

  • 谢谢。它确实给了我资源来弄清楚如何处理我的要求。
【解决方案2】:

如果您只想投影数据中心 dc1.1 的 clusters 字段,那么下面的查询将执行此操作。

db.summary.find({"locations.datacenters": {$elemMatch: {"id": "dc1.1"}}},{"locations.datacenters.clusters":1, _id : 0})

注意,投影中的_id:0用于排除要显示的字段_id。

更多信息可以在以下链接中找到:https://docs.mongodb.com/manual/reference/operator/projection/elemMatch/index.html

【讨论】:

    猜你喜欢
    • 2015-05-12
    • 1970-01-01
    • 2016-02-14
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    相关资源
    最近更新 更多