仅将新属性插入嵌入文档

时间:2015-08-10 03:59:17

标签: mongodb mongodb-query

我希望仅在嵌入文档中没有密钥时才将新值插入到嵌入文档中。例如,我的文档最初是

{
    name: "doc1",
    embeddedDoc: {
        a: 123,
        b: 456
    }
}

然后,如果我要“插入”{b: 789, c: 101},我希望结果为embeddedDoc: {a: 123, b: 456, c: 101}(插入新的c,不要触及现有的b) 。有没有办法做到这一点?

到目前为止,我所拥有的最佳解决方案是在插入对象中为每个元素运行一个查询:

collection.update(
    {"embeddedDoc.b": {$exists: false}},
    {$set: {"embeddedDoc.b": 456}}
)

2 个答案:

答案 0 :(得分:1)

我非常怀疑你可以为许多属性做2次查询。如果您有许多属性,则可以进行第一个查询以获取所有属性,然后知道您拥有的属性,找到缺少的属性作为设置差异。然后只更新缺少的属性。

因此,对于任意数量的属性,最终会得到2个查询和一个简单的应用程序逻辑。请注意,在高度繁忙的应用程序中,query1(find)和query2(update)之间可能会发生一些事情。

答案 1 :(得分:1)

就个人而言,我的文档中没有对象,而是数组。它不会解决不会过度覆盖数据的问题,但它确实可以解决"查找"在"键"使用"数据"可以编入索引。这将是一个很大的"如果您经常打算进行这类更新,则会有所不同。

{
    "name": "Doc1",
    "properties": [
        { "key": "a", "value": 123 },
        { "key": "b", "value": 456 }
    ]
}

所以使用" b"的新数据和" c",然后您可以进行这样的查询尝试:

db.collection.update(
    { "properties.key" { "$nin": [ "b", "c" ]  } },
    { 
        "$push": { 
            "properties": { 
                "$each": [
                    { "key": "b", "value": 789 },
                    { "key": "c", "value": 101 }
                ]
            }
        }
    },
    { "multi": true }
)

如上所述,至少可以"可以"使用一个"键"用$exists查找不能,你至少可以尝试"作为"第一次拍摄"进行此操作,如果文件确实满足给定条件,其中" b"和" c"," key"如果这些文件不受影响,那么这些文件就会受到影响。

后备案例当然是在这里针对每个属性单独进行尝试,但整个过程实际上并不难解决Bulk Operations

var obj = { "b": 456, "c": 101 };

var keys = Object.keys(obj),
    mapped = keys.map(function(key) {
        return { "key": key, "value": obj[key] };
    });

var bulk = intitializeOrderedBulkOp();

bulk.find({ "properties.key": { "$nin": keys } }).update({
    "$push": { "properties": { "$each": mapped } }
});

keys.forEach(function(key) {
    bulk.find({ "properties.key": { "$ne": key } }).update({
        "$push": { "properties": { "key": key, "value": obj[key] } }
    });
});

bulk.execute();

注意到如果第一个查询确实成功了,那么其他一切可能都是" no-op"。但是,如果你用" multi"就像这样,除非你已经知道要测试多少文件,否则你永远无法确定。因此,可能一次发送所有内容"比抱歉更安全"

所以它很简单,代码很简单,因批量操作而往返于服务器,并且效率很高"在查找数据以匹配条件,因为能够使用索引。

"丢弃合并"您想要实现的逻辑总是意味着多次更新。但是,如果你至少让这个过程变得有效,那么#34;尽可能地,这至少要担心一件事。