【问题标题】:Renaming Array Sub-Documents In an Aggregation Result重命名聚合结果中的数组子文档
【发布时间】:2017-11-03 07:27:40
【问题描述】:

我正在使用 mongodb 3.4。运行我的聚合后,我的结果如下所示。我做了两个集合之间的连接。

[   {
    "_id": { // rename _id to main
      "id": "ID_001",
      "name": "Fred flinstone Inc"
    },
    "types": [
      {
        "typeId": "TYPE1",
        "locations": [
          {
            "locationName": "Sydney", // rename locationName to name
            "units": [
              {
                "unitId": "PHG_BTG1" // remove the unitId, i just want the value
              }
            ]
          },
          {
            "locationName": "Brisbane",
            "units": [
              {
                "unitId": "PHG_KTN1"
              },
              {
                "unitId": "PHG_KTN2"
              }
            ]
          }
        ]
      }
    ]   } ]

我想把它投影成

[
  {
    "main": {
      "id": "ID_001",
      "name": "Fred flinstone Inc"
    },
    "types": [
      {
        "typeId": "TYPE1",
        "locations": [
          {
            "name": "Sydney",
            "units": [
              "PHG_BTG1"
            ]
          },
          {
            "name": "Brisbane",
            "units": [
              "PHG_KTN1",
              "PHG_KTN2"
            ]
          }
        ]
      }
    ]
  }
]

我该怎么做?我尝试了 $project 的各种组合但失败了。 示例

{ $project: {
  main: "$_id",
  "_id": 0,
  "types.locations.name": "$types.locations.locationName"
}}

将正确重命名locations.name,但该值显示一个数组 [Sydney, Brisbane] 。当我尝试类似于 locations.units 时也是如此。

我试图再次放松,但它会显示一个空的结果。非常感谢任何帮助。

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    $project 仅以您尝试使用它的形式真正执行“包容性”或“独占性”。因此,虽然您可以通过 "types": { "typeId": 1 } 仅返回数组中的这些项目,但实际上不能仅通过“包含”或“排除”来更改底层结构。

    正如您所发现的,类似:

    { "$project": {
      "types.locations.units": "$types.locations.units.unitId"   
    }}
    

    结果与您的预期不同,因为 MongoDB 将每个值视为“映射”数组元素:

    "types" : [ 
        {
            "locations" : [ 
                {
                    "units" : [ 
                        [ 
                            [ 
                                "PHG_BTG1"
                            ], 
                            [ 
                                "PHG_KTN1", 
                                "PHG_KTN2"
                            ]
                        ]
                    ]
                }
    

    或者更糟:

    { "$project": {
      "types.typeId": "$types.typeId"
    }}
    

    作为:

    "types" : [ 
        {
            "typeId" : [ 
                "TYPE1"
            ]
        }
    ]
    

    所以这里并不真正需要“数组的数组”。这让我们明白为什么这实际上是使用您真正想要使用的以下运算符的“速记”。

    要“转换”数组,请使用$map

    { "$project": {
      "_id": 0,
      "main": "$_id",
      "types": {
        "$map": {
          "input": "$types",
          "as": "t",
          "in": {
            "typeId": "$$t.typeId",
            "locations": {
              "$map": {
                "input": "$$t.locations",
                "as": "l",
                "in": {
                  "name": "$$l.locationName",
                  "units": {
                    "$map": {
                      "input": "$$l.units",
                      "as": "u",
                      "in": "$$u.unitId"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }}
    

    返回你想要的格式:

    {
        "main" : {
            "id" : "ID_001",
            "name" : "Fred flinstone Inc"
        },
        "types" : [ 
            {
                "typeId" : "TYPE1",
                "locations" : [ 
                    {
                        "name" : "Sydney",
                        "units" : [ 
                            "PHG_BTG1"
                        ]
                    }, 
                    {
                        "name" : "Brisbane",
                        "units" : [ 
                            "PHG_KTN1", 
                            "PHG_KTN2"
                        ]
                    }
                ]
            }
        ]
    }
    

    基本上每个“数组”都被“重新映射”为仅返回您实际指定的内部表示的结构。这就是为什么要将 $map 嵌套在其他 $map 表达式中,以处理每个数组元素的内部数组。

    还要注意,由于我们本质上是“重写”"type" 属性,$project 中同名属性的默认行为通常是“复制”并保留顺序,实际上是 "types"是现有文档结构的一部分,"main" 不是。因此,"types" 将通过标准投影包含“首先”表示。

    “重写”意味着这被认为是一个新元素,因此键的顺序现在与投影中的相同,即 "main" 先于 "type",而不是相反。

    【讨论】:

      猜你喜欢
      • 2020-05-01
      • 2020-05-09
      • 2015-10-19
      • 2015-02-03
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多