MongoDB-使用另一个子数组字段更新父数组字段

时间:2020-05-10 12:27:41

标签: mongodb

我有这样的收藏

$ tldr +RTS --info -RTS
 [("GHC RTS", "YES")
 ,("GHC version", "8.6.5")
 ,("RTS way", "rts_thr")
 ,("Build platform", "x86_64-unknown-linux")
 ,("Build architecture", "x86_64")
 ,("Build OS", "linux")
 ,("Build vendor", "unknown")
 ,("Host platform", "x86_64-unknown-linux")
 ,("Host architecture", "x86_64")
 ,("Host OS", "linux")
 ,("Host vendor", "unknown")
 ,("Target platform", "x86_64-unknown-linux")
 ,("Target architecture", "x86_64")
 ,("Target OS", "linux")
 ,("Target vendor", "unknown")
 ,("Word size", "64")
 ,("Compiler unregisterised", "NO")
 ,("Tables next to code", "YES")
 ]

现在我希望最终结果像

db.aa1.insertMany([
    { parentArr: [] },
    { parentArr: [
        {childArr: [ {childField: 2}, {childField: 4} ]}
    ] },
    { parentArr: [
        {childArr: []}
    ] },
    { parentArr: [
        {childArr: [ {childField: 3}, {childField: 5} ]}
    ] },
])

在这里,我复制了 parentArr.parentField中的childArr.childField值。

现在在普通的JS中,我可以做这样的事情

[
    { parentArr: [] },
    { parentArr: [ { childArr: [] } ] },
    { parentArr: [
        { 
          childArr: [ {childField: 2}, {childField: 4} ],
          parentField: [2, 4]
        },
    ] },
    { parentArr: [
        { 
          childArr: [ {childField: 3}, {childField: 5} ],
          parentField: [3, 5]
        }
    ] },
]

如何使用MongoDB查询实现这一目标?

我当然尝试了以下$ push $ set组合。

为示例起见,我已经编写了所有push并一起设置。

parentArr.forEach(p => p.parentField = p.childArr ? p.childArr.map(c => c.childField) : [])

1 个答案:

答案 0 :(得分:1)

如果您使用的是Mongo 4.2及更高版本,他们会引入pipeline'd updates,这意味着我们现在在更新时拥有更多功能:

db.aa1.updateMany(
    {
        "parentArr.childArr.childField": {$exists: true}
    },
    [
        {
            $set: {
                "parentArr.parentField": {
                    $reduce: {
                        input: {
                            $map: {
                                input: "$parentArr",
                                as: "parent",
                                in: {
                                    $map: {
                                        input: "$$parent.childArr",
                                        as: "child",
                                        in: "$$child.childField"
                                    }
                                }
                            }
                        },
                        initialValue: [],
                        in: {$setUnion: ["$$value", "$$this"]}
                    }
                }
            }
        }
    ]
)

如果您使用的是较旧的Mongo版本,则必须在代码中进行此操作,因为您已经发布了相关的代码段,因此我无需添加任何内容。