mongodb多层嵌套数组更新。

如何使用mongo shell或者js脚本来对mongodb中多层嵌套数组中的字段更新?

经过查询发现“$”占位符不能使用两次(存疑)?进而转向js,但是资料都是如何查询,没有更新。

如图为我的数据结构,是一个文档,panels是最外层数组,condition是第二层数组,需要更新的是valueConnection的值。

clipboard.png

希望可以得到:

1、mongoshell如何解决多层嵌套数组更新。

2、js如何解决多层嵌套数组更新。

(以上皆在不指定数组下标的情况,只能通过匹配valueConnection的值是否为“changed”来定位)

非常感谢。

阅读 8.3k
3 个回答

通过查询最新官方文档发现在3.6版本已更新一个$[identifier]的operator (经验:一定看原版官网文档,中文版由于翻译工作需要时间版本较为滞后)与本情况相似的例子在官方文档最下面。
arrayFilters过滤器可以将符合条件的字段筛选出来,再进行你想要的的操作。由于我的目的是所有valueConnection的值为“before”的字段都要修改,所以不可以指定数组下标,在这里使用两次 $[<identifier>],并在arrayFilters中对其过滤。

db.reportconfigs.update(
   {},
   {  $set: {  "panels.$[outter].condition.$[inner].valueConnection":"after"  }  },
   {  arrayFilters : [ {  "outter.condition": {$ne: null} },{  "inner.valueConnection":"before"  }  ], multi :true } 
)

需要注意的是:“{ "outter.condition": {$ne: null} }”,对于我的数据结构来说相当重要,如果不添加会报错($ne=not equal)。
如下图:

clipboard.png

因为condition在有的文档中为“null”,我们必须筛去这些为null的字段,个人认为如果你的数据中不会出现null的情况可以不加。
可能报错原因: $[<identifier>]必须大于3.6版本。

以上为嵌套数组更新解决方案,如有错请多指教。

新手上路,请多包涵

使用 mongodb 的 $[<identifier>], 可以进行嵌套数组的批量更新。mongodb 要求版本 >= 3.6

代码示例如下:

// 插入 demo 数据
db.demo.insert({
    "panels": [
        {
            "id": 10000,
            "condition": [
                {
                    "valueConnection": "changed",
                    "valueSource": 111
                },
                {
                    "valueConnection": "nochanged",
                    "valueSource": 122
                },
                {
                    "valueConnection": "nochanged",
                    "valueSource": 133
                },
                {
                    "valueConnection": "changed",
                    "valueSource": 144
                }
            ]
        },
        {
            "id": 20000,
            "condition": [
                {
                    "valueConnection": "changed",
                    "valueSource": 211
                },
                {
                    "valueConnection": "nochanged",
                    "valueSource": 222
                },
                {
                    "valueConnection": "nochanged",
                    "valueSource": 233
                }
            ]
        }
    ]
})

// 执行更新操作
db.demo.update({}, {
    $inc: {
        "panels.$[t].condition.$[val].valueSource": 100001
    }
}, {
    arrayFilters: [{
        "t.id": 10000
    }, {
        "val.valueConnection": "changed"
    }],
    multi: true
});

更新后结果:

更新后结果

具体更详细的说明,参考官方介绍文档: https://docs.mongodb.com/manu...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题