仅在满足条件mongodb时才在更新时创建文档

时间:2014-06-01 01:45:07

标签: mongodb upsert

请参阅下面的mongo查询。 我希望能够在符合条件的情况下更新文档。 如果不满足x或y,我想创建一个新文档但是如果满足x和y但我不想创建新文档但是z有值

 collection.update({ x : 1, y : 2, z : {$exists : false} }, {field_to_update : update}, { upsert :true })

2 个答案:

答案 0 :(得分:1)

解决方案是在前两个字段上创建唯一的复合索引。感谢

答案 1 :(得分:0)

有一种可能的"这样做的方法,但你必须非常小心你甚至考虑在这里。请考虑以下初始文档:

{ "x" : 1, "y" : 2, "z" : 4, "a" : 2 }
{ "x" : 1, "y" : 2, "a" : 2 }
{ "x" : 1, "y" : 2, "z" : 5, "a" : 4 }
{ "x" : 4, "y" : 2, "a": 1 }

您的基本条件是说您希望匹配" x"和" y"但只有在" z"上没有匹配时才插入新文件;任何价值。据推测,如果" x"和" y"如果您不想匹配,则需要插入新文档。

这里的主要考虑因素是"其中"你想要更新文件吗?上面可能有多个匹配这个条件,理想情况下匹配这里的两个文档,而不是具有{ "x": 1, "y": 2 }但没有" z"的值的文档。如果您对此作为逻辑原理没有问题,那么可能会使用以下内容:

db.test.update(
    { 
        "x": 1, 
        "y": 2, 
        "z": { "$exists": true },
    }, 
    { 
        "$set": { "a": 3 }, 
        "$setOnInsert": { "z": 3 }
    },
    { 
        "multi": true, 
        "upsert": true
    }
)

这里的重要部分是$exists运营商的使用,因为您不想修改任何根本没有任何内容的东西。" z"完全可以,如果需要,您还可以将其限制为数字类型,但主要缺点是您不想更新的文档。

由于您没有指定" z"的值。为了在查询方面进行匹配,当你" upsert"时,你可能确实有你想要的东西,所以在$setOnInsert修饰符中包含它,因为我们显示条件不匹配时会发生什么:

db.test.update(
    { 
        "x": 4, 
        "y": 2, 
        "z": { "$exists": true },
    }, 
    { 
        "$set": { "a": 3 }, 
        "$setOnInsert": { "z": 3 }
    },
    { 
        "multi": true, 
        "upsert": true
    }
)

因此,虽然有一个文件,但#34; x"和" y"如声明中所述,它对" z"没有任何价值。所以" upsert"会插入一个新文档。条件。这两个语句的结果文件现在看起来像这样:

{ "x" : 1, "y" : 2, "z" : 4, "a" : 3 }
{ "x" : 1, "y" : 2, "a" : 2 }
{ "x" : 1, "y" : 2, "z" : 5, "a" : 3 }
{ "x" : 4, "y" : 2, "a" : 1 }
{ "x" : 4, "y" : 2, "a" : 3, "z" : 3 }

只要您能够考虑到"任何价值"为" z"很容易导致多个文档被更新,这就是处理" upsert"你想要的条件。