【问题标题】:MongoDB project part of the array elementMongoDB项目部分数组元素
【发布时间】:2020-10-30 06:31:32
【问题描述】:

我正在尝试创建一个投影,我可以在其中仅获取 Array 元素的一部分。

以本文档为模型:

{
    "city_info": {
        "name": "First City"
        "initials": "FC"
    },
    "postal_codes": {
        "ranges": [
            {
                "name": "Range 1",
                "details": "More details",
                "another_object": {
                   (...)
                },
                "codes": [
                    {"code": 1},
                    {"code": 2},
                    {"code": 3}
                ]
            },
            {
                "name": "Range 2",
                "details": "More details 2",
                "another_object": {
                   (...)
                }
                "codes": [
                    {"code": 4},
                    {"code": 5}
                ]
            }
        ]
    }
}

我的查询看起来像{"postal_codes.ranges.codes.code": 3}

范围和代码可以包含数百个元素。 "another_object" 只是一个占位符,例如。

预期回报如下:

{
    "city_info": {
        "name": "First City"
        "initials": "FC"
    },
    "range": {
        "name": "Range 1",
        "details": "More details",
        "another_object": {
            (...)
        }
    }         
}

简而言之,我也需要获取与查询匹配的数组元素,但不要完全返回。

似乎 find 不够强大,我需要某种聚合。我尝试使用匹配来仅返回与查询匹配的文档,但我不知道如何仅投影数组的一部分。

【问题讨论】:

  • 您的 JSON 结构无效。 "codes": [ "code": 4, "code": 5 ] 应该是 "codes": [{ "code": 4, "code": 5 }]。不是吗?
  • 注意到了,我用代码将它固定到一个对象数组中。

标签: mongodb aggregation-framework


【解决方案1】:

您需要使用$unwindArray转换为Objects,然后使用$match

试试这个查询,

db.collection.aggregate([
  { "$unwind": "$postal_codes" },
  { "$unwind": "$postal_codes.ranges.codes"},
  { "$match" : { "postal_codes.ranges.codes" : { "$eq": 3 } }},
  { "$project" : { "city_info": 1, "ranges": "$postal_codes.ranges" }}
])

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    您的codes 结构无效。这个不能插入到MongoDB中

    "codes": [
      "code": 1,
      "code": 2,
      "code": 3
    ]
    

    如果您需要保留三个代码,则有效的 JSON 将是

    "codes": [
      1,2,3
    ]
    

    所以样本数据:

    {
        "_id" : ObjectId("5f074307e96d8884b6bdbdd5"),
        "city_info" : {
            "name" : "First City",
            "initials" : "FC"
        },
        "postal_codes" : {
            "ranges" : [ 
                {
                    "name" : "Range 1",
                    "details" : "More details",
                    "another_object" : {},
                    "codes" : [ 
                        1, 
                        2, 
                        3
                    ]
                }, 
                {
                    "name" : "Range 2",
                    "details" : "More details 2",
                    "another_object" : {},
                    "codes" : [ 
                        4, 
                        5
                    ]
                }
            ]
        }
    }
    

    查询获取:

    db.getCollection('test2').aggregate([
      {
        $unwind: "$postal_codes.ranges"
      },
      {
        $unwind: "$postal_codes.ranges.codes"
      },
      {
        $match: {
          "postal_codes.ranges.codes": 3
        }
      }
    
    ])
    

    输出:

    /* 1 */
    {
        "_id" : ObjectId("5f074307e96d8884b6bdbdd5"),
        "city_info" : {
            "name" : "First City",
            "initials" : "FC"
        },
        "postal_codes" : {
            "ranges" : {
                "name" : "Range 1",
                "details" : "More details",
                "another_object" : {},
                "codes" : 3
            }
        }
    }
    

    为避免在输出中出现codes,您需要使用$project 作为最后一个管道

    {
     $project:{"postal_codes.ranges.codes":0}
    }
    

    【讨论】:

      猜你喜欢
      • 2014-02-25
      • 2021-12-20
      • 1970-01-01
      • 2021-12-22
      • 2021-03-16
      • 1970-01-01
      • 2022-08-23
      • 1970-01-01
      相关资源
      最近更新 更多