mongo forEach unable to update array in document
我正在尝试编写在RoboMongo中运行的mongo脚本,该脚本将遍历集合中的所有文档。每个文档包含一个数组
1 2 3 4 5 6 | { "name":"myApp", "myArray": [ {"env":"dev","dbHost":"db2dev.local" }, {"env":"prod", "dbHost":"db1prod.local" } ] |
我想将dev中定义的dbHost字段复制到prod。因此,以上结果将是:
1 2 3 4 5 6 | { "name":"myApp", "myArray": [ {"env":"dev","dbHost":"db2dev.local" }, {"env":"prod", "dbHost":"db2dev.local" } ] |
当我尝试访问字段
1 | TypeError: myDoc.myArray[0] is undefined |
该函数是这样的:
1 2 3 4 5 6 7 8 9 10 11 | db.myCollection.find().forEach( function(myDoc) { var devIdx = 0; var prodIdx = 1; if (myDoc.myArray[0].env !== 'dev')} devIdx = 1; prodIdx = 0; } myDoc.myArray[prodIdx].dbHost = myDoc.myArray[devIdx].dbHost; print(myDoc); }); |
我已经检查了集合(非常小),每个文档都有一个
我在做什么错?在mongo脚本中使用的正确语法是什么?是否不支持更新文档中的数组?
寻找解决方案
我已经搜索并找到了每个示例,但是大多数示例都是微不足道的,并且都不包含正在访问或更改的数组。
mongo文档也非常简单:https://docs.mongodb.com/v3.6/reference/method/cursor.forEach/
Mongo javascript不允许您像尝试做的那样直接访问数组(除非您处于for循环中)。因此,解决方案如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | db.myCollection.find({}).forEach( function(myDoc) { var foundDevEntry = null; var updatedProdEntry = false; // First time loop to get a copy of the dev entry for (var idx in myDoc.myArray) { if (myDoc.myArray[idx].env === 'dev') { foundDevEntry = myDoc.myArray[idx]; } } // 2nd time loop to update the value for (var idx in myDoc.myArray) { if (myDoc.myArray[idx].env === 'prod') { myDoc.myArray[idx].dbHost = foundDevEntry.dbHost; } } // Now update the database with this change db.myCollection.update({_id: myDoc._id}, {$set: {"myArray": myDoc.myArray}}); print(myDoc); // So results are also returned when query is run }); |
我删除了错误检查,以专注于所需的更改。 (对我来说)奇怪的是语法
以下参考文献帮助我提出了解决方案:
-
在mongodb shell上的forEach中更新
-
https://www.mysoftkey.com/mongodb/how-to-use-foreach-loop-in-mongodb-to-manipulate-document/
我应该补充一点,我读过的一些解决方案说要更新阵列,您必须重新构建阵列(https://stackoverflow.com/a/22657219/3281336)。我没有在我的解决方案中做到这一点,但它确实起作用,但想分享它。