MongoDb 中是否有 $arrayToObject 的替代品

Is there any substitute of $arrayToObject in MongoDb

我有一个反转对象键和值的要求。我有以下类型的数据:

[
        "elements": {
            "title": "elem_1_6_title",
            "sub_title": "elem_1_6_sub_title",
            "media": "elem_1_6_media",
            "button": "elem_1_6_button",
            "give_us_call": "elem_1_6_give_us_call"
        },
        "elements": {
            "title": "elem_1_6_title",
            "sub_title": "elem_1_6_sub_title"
        },
        "elements": {}
    ]

预期输出:

[
    "elements": {
        "elem_1_6_title": "title",
        "elem_1_6_sub_title": "sub_title",
        "elem_1_6_media": "media",
        "elem_1_6_button": "button",
        "elem_1_6_give_us_call": "give_us_call"
    },
    "elements": {
        "elem_1_6_title": "title",
        "elem_1_6_sub_title": "sub_title"
    },
    "elements": {}
]

管道:

[
    {
        "$addFields": {
            "sec_elems_arr": {
                "$objectToArray": "$elements"
            }
        }
    },
    {
        "$unwind": {
            "path": "$sec_elems_arr",
            "preserveNullAndEmptyArrays": true
        }
    },
    {
        "$addFields": {
            "section_elements": {
                "$arrayToObject": [
                    [
                        {
                            "k": "$sec_elems_arr.v",
                            "v": "$sec_elems_arr.k"
                        }
                    ]
                ]
            }
        }
    }
]

以上管道抛出错误:

 $arrayToObject requires an object keys of 'k' and 'v'. Found incorrect number of keys:0

因为上述元素对象之一没有键值。但是这种情况可以存在于数据中。如何使用 MongoDB 聚合管道实现此目的?

我认为问题更多是关于您使用 $arrayToObject 不正确。您可以将它与 $map 一起使用以正确交换 k-v.

db.collection.aggregate([
  {
    $addFields: {
      elements: {
        "$objectToArray": "$elements"
      }
    }
  },
  {
    "$addFields": {
      "elements": {
        "$arrayToObject": {
          "$map": {
            "input": "$elements",
            "as": "e",
            "in": {
              k: "$$e.v",
              v: "$$e.k"
            }
          }
        }
      }
    }
  }
])

这里是Mongo playground供大家参考。

注意上面的答案可以通过调用 $objectToArray 作为 $map 的输入来进一步优化。这节省了一个阶段——总是一件好事。

db.collection.aggregate([
  {
    "$addFields": {
      "elements": {
        "$arrayToObject": {
          "$map": {
            "input": {"$objectToArray": "$elements"},
            "as": "e",
            "in": {
              k: "$$e.v",
              v: "$$e.k"
            }
          }
        }
      }
    }
  }
])