MongoDB : 对多个字段进行单次更新 V/S 对单个字段进行多次更新?

MongoDB : Single update on multiple fields V/S Multiple updates on single field?

我有一个包含 7 个数组的集合,每个数组包含 1000 多个子文档。

{  
    "_id": 1,
    "arr1": [
        { "date": 20100101, "time": 120000, "key": "value1" },
        { "date": 20100401, "time": 121500, "key": "value2" },
        ...
        { "date": 20161001, "time": 120000, "key": "valueN" },
    ],
    .
    .
    "arr7": [
        { "date": 20100101, "time": 120000, "key": "value1" },
        { "date": 20100401, "time": 121500, "key": "value2" },
        ...
        { "date": 20161001, "time": 120000, "key": "valueN" },
    ]
}

我想从所有数组中提取早于特定日期的活动。 我应该执行一次更新,它会立即从每个数组中提取匹配的子文档,即

db.collection.updateMany({}, { $pull: { arr1: { date: { $lt: 151031 } }, arr2: { date: { $lt: 151031 } }, ... arr7: { date: { $lt: 151031 } } } })

或者我应该为每个数组分别执行更新。即

db.collection.updateMany({}, { $pull: { arr1: { date: { $lt: 20160101 } } } })
db.collection.updateMany({}, { $pull: { arr2: { date: { $lt: 20160101 } } } })
...
db.collection.updateMany({}, { $pull: { arr7: { date: { $lt: 20160101 } } } })

哪个更有效?

我会说你应该使用一个查询从所有数组中提取

db.collection.updateMany({}, { $pull: { arr1: { date: { $lt: 151031 } }, arr2: { date: { $lt: 151031 } }, ... arr7: { date: { $lt: 151031 } } } })

这使 mongo 查询优化器可以完全控制执行。例如,它可能只需要访问每个对象一次而不是七次。

您应该使用 explain() 查看查询的确切执行情况(参见 https://docs.mongodb.com/v3.2/reference/method/cursor.explain/)。

您可能还需要考虑更改数据模型,因为您可能会遇到 mongo 每个文档限制 16MB 的问题。此外,mongo 中的数组索引对于如此庞大的数组来说效率非常低。