嵌套 MongoDB 数组中的条件$inc



我的数据库看起来像这样:

{
 _id: 1,
 values: [ 1, 2, 3, 4, 5 ]
},
{
 _id: 2,
 values: [ 2, 4, 6, 8, 10 ]
}, ...

我想更新每个文档的嵌套数组("值")中满足某些条件的每个值。例如,我想将>= 4 的每个值递增 1,这应该产生:

{
 _id: 1,
 values: [ 1, 2, 3, 5, 6 ]
},
{
 _id: 2,
 values: [ 2, 5, 7, 8, 11 ]
}, ...

我习惯于使用 SQL,其中嵌套数组将是使用唯一 ID 连接的单独表。我在这个新的NoSQL世界中有点迷茫。

谢谢你,

使用嵌套数组实际上不可能进行这种更新,其原因在位置$运算符文档中给出,并且指出您只能匹配查询中给定条件的第一个数组元素。

所以像这样的声明:

db.collection.update(
    { "values": { "$gte": 4 } },
    { "$inc": { "values.$": 1 } }
)

在只有匹配的"第一个"数组元素将递增的意义上不起作用。所以在你的第一个文档中,你会得到这个:

{ "_id" : 1, "values" : [  1,  2,  3,  6,  6 ] }

为了按照您的建议更新值,您需要迭代文档和数组元素以生成结果:

db.collecction.find({ "values": { "$gte": 4 } }).forEach(function(doc) {
    for ( var i=0; i < doc.values.length; i++ ) {
        if ( doc.values[i] >= 4 ) {
            doc.values[i]++;
        }
    }
    db.collection.update(
        { "_id": doc._id },
        { "$set": { "values": doc.values } }
    );
})

或者任何等同于该基本概念的代码。

一般来说,这种更新不适合在数组中包含元素的结构。如果这确实是您的需求,那么最好将这些元素列在单独的集合中。

再说一次,这个问题的呈现更像是一种"假设"的情况,而不了解您执行此类 udpate 的实际用例。因此,如果您可能在另一个问题中描述了您实际需要做什么以及您的数据的真实外观,那么就您使用的最佳方法而言,这可能会得到更有意义的响应。