关于mongodb:mongo forEach无法更新文档中的数组

mongo forEach unable to update array in document

我正在尝试编写在RoboMongo中运行的mongo脚本,该脚本将遍历集合中的所有文档。每个文档包含一个数组myArray。这些文档如下所示:

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" }
  ]

当我尝试访问字段myArray[0]时,出现语法错误:

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);
});

我已经检查了集合(非常小),每个文档都有一个myArray字段,在数组中正好有两个值(一个用于dev,一个用于prod)。 >

我在做什么错?在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
});

我删除了错误检查,以专注于所需的更改。 (对我来说)奇怪的是语法myDoc.myArray[idx]实际上是有效的,但仅在循环内有效!

以下参考文献帮助我提出了解决方案:

  • 在mongodb shell上的forEach中更新

  • https://www.mysoftkey.com/mongodb/how-to-use-foreach-loop-in-mongodb-to-manipulate-document/

我应该补充一点,我读过的一些解决方案说要更新阵列,您必须重新构建阵列(https://stackoverflow.com/a/22657219/3281336)。我没有在我的解决方案中做到这一点,但它确实起作用,但想分享它。