MongoDB更新了nest数组的查询

时间:2014-03-17 01:27:29

标签: node.js mongodb dictionary

收集测量如下所示:

{
    "Data" : [ [-5, [[1, 1023.0], [2, 694.0]]], [-1, [[1, 0.0], [2, 20.0]]], [-3, [[1, 30.75], [2, 30.75]]] ]
} 

它反映了Dictionary<int, Dictionary<int, double>>的c#结构 - 我需要做的是编写一个更新脚本,它将为所有父母字典键添加5。怎么可以通过mongo更新脚本来完成?所以它会把对象看起来如下:

{
    "Data" : [ [0, [[1, 1023.0], [2, 694.0]]], [4, [[1, 0.0], [2, 20.0]]], [2, [[1, 30.75], [2, 30.75]]] ]
}

2 个答案:

答案 0 :(得分:1)

执行此操作的唯一方法是以编程方式,即循环数据数组并单独更新每个数据。

答案 1 :(得分:1)

如果您需要以这种方式更新内容,这可能不是您真正想要的结构。问题在于能够匹配nested array中的元素,因为当前限制是您只能匹配第一个位置并且仅在 时引用做更新。

根据你所呈现的内容,我们无法详细说明你的目的,但你可能需要的是这样的:

{
    "Data" : [
        { 
            "pos": 0,
            "ref": -5, 
            "A": { "x": 1, "y": 1023.0  }, 
            "B": { "x": 2, "y": 694.0 }
        },
        {
            "pos": 1, 
            "ref": -1, 
            "A": { "x": 1, "y": 0.0},
            "B": { "x": 2, "y": 20.0 }
        },
        {
            "pos": 2,
            "ref": -3, 
            "A": { "x": 1, "y": 30.75 },
            "B": { "x": 2, "y": 30.75 }
        }
    ]
}

然而,即使这样也不允许您在单个查询中进行更新。你可以为每个元素做一个:

db.collection.update({"_id": id, "Data.pos": 0}, {"$inc":{"Data.$.ref": 5}});
db.collection.update({"_id": id, "Data.pos": 1}, {"$inc":{"Data.$.ref": 5}});
db.collection.update({"_id": id, "Data.pos": 3}, {"$inc":{"Data.$.ref": 5}});

并且您当前的架构不允许您执行此操作。并且至少所有元素都可以通过这种方式访问​​,而这在以前也是如此。

在任何情况下,除了循环外,不可能一次更新所有数组元素:

db.collection.find({ "_id": id }).forEach(function(doc) {
    doc.Data.forEach(function(data) {
        data.ref += 5;
    });
    db.collection.update(
      { "_id": doc._id },
      { "$set": { "Data": doc.Data } }
    );
}) 

或者某些变体甚至可能像第一个例子那样做,而不是像这样替换整个数组。您当前的结构将依赖于循环遍历多个嵌套数组来执行相同的操作。

当然,如果您经常需要以这种方式更新所有元素,那么请考虑除数组之外的其他内容。或者根据您的数据访问需求,了解您必须更新的方式。

阅读有关如何处理事情的文档,并从那里做出决定。