【问题标题】:Add subdocument for each document in array dynamically为数组中的每个文档动态添加子文档
【发布时间】:2022-02-07 10:13:34
【问题描述】:

我想为名称为arrayName_index 的子数组中的每个文档设置$addField(不知道数组有多长)。

例如: 我有一个有趣的活动集合,如下所示:

{
_id: "1", 
activity: movie,
attendees: [
 {firsName: "personA", lastName: "lasty"},
 {firsName: "personB", lastName: "namey"},
 {firsName: "personC", lastName: "blabla"}
]},
{
_id: "2", 
activity: bowling,
attendees: [{firsName: "personA", lastName: "lasty"}]
}

我想要一个 mongodb 聚合来创建输出为:

{
_id: "1", 
activity: movie,
attendees: [
 {firsName: "personA", lastName: "lasty"},
 {firsName: "personB", lastName: "namey"},
 {firsName: "personC", lastName: "blabla"}
],
attendees_1: {firsName: "personA", lastName: "lasty"},
attendees_2: {firsName: "personB", lastName: "namey"},
attendees_3: {firsName: "personC", lastName: "blabla"},
},
{
_id: "2", 
activity: bowling,
attendees: [{firsName: "personA", lastName: "lasty"}],
attendees_1: {firsName: "personA", lastName: "lasty"}
}

【问题讨论】:

    标签: mongodb mongoose mongodb-query aggregation-framework nosql-aggregation


    【解决方案1】:

    有点长且复杂的查询。

    概念

    1.0 $replaceRoot - 将输入文档替换为特定文档

    1.1 $mergeObjects - 将当前文档 ($$ROOT) 与 1.2 中生成的对象合并。

    1.2 $arrayToObject - 将数组从 1.3 转换为单个文档。

    1.3 $reduce - 迭代数组中的每个元素并将其转换为单个值。

    1.4 $concatArrays - 合并数组。

    1.4.1 创建文档

    1.4.1.1 k(key)前缀为“attendees_”,获取当前迭代文档的索引($indexOfArray)+1。

    1.4.1.2 v(值)与当前迭代文档。

    db.collection.aggregate([
      {
        "$replaceRoot": {
          "newRoot": {
            "$mergeObjects": [
              "$$ROOT",
              {
                "$arrayToObject": {
                  "$reduce": {
                    "input": "$attendees",
                    "initialValue": [],
                    "in": {
                      "$concatArrays": [
                        "$$value",
                        [
                          {
                            k: {
                              "$concat": [
                                "attendees_",
                                {
                                  "$toString": {
                                    "$add": [
                                      {
                                        "$indexOfArray": [
                                          "$attendees",
                                          "$$this"
                                        ]
                                      },
                                      1
                                    ]
                                  }
                                }
                              ]
                            },
                            v: "$$this"
                          }
                        ]
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    ])
    

    Sample Mongo Playground

    【讨论】:

    • 有效!谢谢!
    【解决方案2】:

    可能会稍微好一点,因为这避免了数组搜索,但它与永顺的答案大致相同。

    db.collection.aggregate([
      {
        "$replaceRoot": {
          "newRoot": {
            "$mergeObjects": [
              "$$ROOT",
              {
                "$arrayToObject": {
                  "$reduce": {
                    "input": { "$range": [ 0, { "$size": "$attendees" } ] },
                    "initialValue": [],
                    "in": {
                      "$concatArrays": [
                        "$$value",
                        [
                          {
                            k: {
                              "$concat": [
                                "attendees_",
                                { "$toString": { "$add": [ 1, "$$this" ] } }
                              ]
                            },
                            v: { "$arrayElemAt": [ "$attendees", "$$this" ] }
                          }
                        ]
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    ])
    

    试试mongoplayground.net

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-29
      • 2014-07-29
      • 2021-12-02
      • 2012-09-28
      • 2015-07-01
      • 1970-01-01
      • 2015-02-16
      • 2014-04-01
      相关资源
      最近更新 更多