【问题标题】:MongoDB: How do I aggregate the values for each field of an object into a set while keeping the field name?MongoDB:如何在保留字段名称的同时将对象的每个字段的值聚合到一个集合中?
【发布时间】:2022-10-13 05:13:14
【问题描述】:

给定一个将任意标签存储为键值对的数据结构。

标签对象的字段名称对应于键,因此事先不知道。

如何将多个此类文档聚合为一个,以便它包含每个标签的字段以及包含出现值的数组?

输入:

{
    "_id" : ObjectId("6346826e3b4cd5a90b20b75b"),
    "tags" : {
        "planet" : "earth",
        "color" : "blue"
    }
}


{
    "_id" : ObjectId("634683723b4cd5a90b20b819"),
    "tags" : {
        "planet" : "earth",
        "color" : "green",
        "foo" : "bar"
    }
}


{
    "_id" : ObjectId("634683823b4cd5a90b20b829"),
    "tags" : {
        "foo" : "acme",
        "color" : "red",
        "xyz" : "1"
    }
}

预期输出:

{
    "_id" : ObjectId("634684063b4cd5a90b20b87f"),
    "tags" : {
        "planet" : [ "earth" ],
        "color" : [ "blue", "green", "red" ],
        "foo" : [ "bar", "acme" ],
        "xyz" : [ "1" ]
    }
}

【问题讨论】:

    标签: aggregation-framework


    【解决方案1】:
    db.collection.aggregate([
      {
        $replaceRoot: {
          newRoot: {
            a: {
              $objectToArray: "$tags"
            }
          }
        }
      },
      {
        "$group": {
          "_id": "group by expression",
          "field": {
            $push: "$a"
          }
        }
      },
      {
        "$addFields": {
          "field": {
            "$reduce": {
              "input": "$field",
              "initialValue": [],
              "in": {
                "$concatArrays": [
                  "$$value",
                  "$$this"
                ]
              }
            }
          }
        }
      },
      {
        "$unwind": "$field"
      },
      {
        "$group": {
          "_id": "$field.k",
          "v": {
            "$addToSet": "$field.v"
          }
        }
      },
      {
        "$addFields": {
          "m": [
            {
              "k": "$_id",
              "v": "$v"
            },
            
          ]
        }
      },
      {
        "$project": {
          a: {
            "$arrayToObject": "$m"
          }
        }
      },
      {
        $replaceRoot: {
          newRoot: "$a"
        }
      },
      
    ])
    

    看起来很相似:)

    [
      {
        "foo": [
          "bar",
          "acme"
        ]
      },
      {
        "planet": [
          "earth"
        ]
      },
      {
        "xyz": [
          "1"
        ]
      },
      {
        "color": [
          "green",
          "red",
          "blue"
        ]
      }
    ]
    

    https://mongoplayground.net/p/kTa3awcKdB2

    “分阶段输出”下拉菜单有助于理解它的工作原理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 2020-07-24
      • 1970-01-01
      • 2019-03-23
      相关资源
      最近更新 更多