MongoDB聚合:将数组聚合为键控对象

MongoDB聚合:将数组聚合为键控对象,mongodb,aggregation-framework,Mongodb,Aggregation Framework,我想使用聚合功能将文档数组展平为键控对象。以下是我的文档示例: [ { "_id": 1, "texts": [ { "language": "english", "text": "hello" }, { "language": "german", "text": "hallo" }, { "language": "french", "text": "bonjour" }

我想使用聚合功能将文档数组展平为键控对象。以下是我的文档示例:

[ 
    {
        "_id": 1,
        "texts": [
            { "language": "english", "text": "hello" },
            { "language": "german", "text": "hallo" },
            { "language": "french", "text": "bonjour" }
        ]
    }, …
]
预期结果:

[
     {
        "_id": 1,
        "texts": {
            "english": "hello",
            "german": "hallo",
            "french": "bonjour"
        }
    }, …
]
我已经研究了不同的操作符,例如,
$map
,但这似乎集中在数组到数组的转换上。我可能需要一个相当于JS的
$reduce
,但找不到将值累积到对象中的方法

有什么想法吗?

您可以在mongodb3.4.4及更高版本中尝试使用和聚合

只需使用键(k)转换
语言
字段,使用值(v)转换文本,并使用

您需要和,它将k-v对数组转换为单个对象:

db.col.aggregate([
    {
        $addFields: {
            texts: {
                $arrayToObject: {
                    $map: {
                        input: "$texts",
                        as: "text",
                        in: {
                            k: "$$text.language",
                            v: "$$text.text"
                        }
                    }
                }
            }
        }
    }
])
您还可以使用with

差不多

db.col.aggregate([{
  "$project": {
    "texts":{
     "$arrayToObject":{
       "$zip": {
        "inputs": [
          "$texts.language",
          "$texts.text"
        ]
      }
    }
  }}
}])

非常感谢您的快速回答+1两者完全同时进行,并且同样有效。我之所以接受米克尔的答案而不是你的答案,是因为我更喜欢把所有东西都放在一个管道阶段。干杯有趣的更新:我实际上仍然在运行MongoDB 3.4.6——聚合仍然可以正常工作。不知道为什么。。。但是,
$arrayToObject
已经在mongodb 3.6中引入,这就是他们宣布的方式。请注意,那不是真的它从v3.4.4开始出现:@dnickless oops!!!我错了。。。谢谢你报应我。。。更新的答案很酷,甚至更简洁。明天将尝试并给出反馈。谢谢!
db.col.aggregate([{
  "$project": {
    "texts":{
     "$arrayToObject":{
       "$zip": {
        "inputs": [
          "$texts.language",
          "$texts.text"
        ]
      }
    }
  }}
}])