mongodb upsert是否使用查询字段

问题描述:

当使用upsert更新时,驱动程序将查询和$ set对象组合在一起。mongodb upsert是否使用查询字段

下面是一些示例代码

db.collection('objects').update({_key: 'test1'}, {$set: {a:1}}, {upsert: true, w: 1}, callback); 

当我这样做,如果文件test1不存在蒙戈似乎插入下面的文件。

{ 
_id: , 
_key: 'test1', 
    a: 1 
} 

因此,从查询需要的关键,并将其作为一个字段a:1

沿着这是任何不同于:

var data = { 
    _key : 'test1', 
    a: 1 
}; 

db.collection('objects').update({_key: 'test1'}, {$set: data}, {upsert: true, w: 1}, callback); 

是第二个要因慢覆盖_key。在_key上有一个索引。

基本上没有,查询中指定的值不会覆盖匹配该查询的文档存在的位置。

"upsert"基本上的工作原理是查询部分中设置的条件首先查找符合这些条件的文档。在文档存在的地方,那么声明的“更新文档”部分中提供的任何参数都将用于写入匹配的文档。在这种情况下,只有$set运算符指定了字段,所以这些是唯一被触摸的字段,而不是发送覆盖现有文档的整个对象。

如果文档不匹配,则首先将查询条件中指定的任何值写入新文档。这是有道理的,因为你要求的文件符合这些条件但不在那里。

然后(但实际上一次)声明的“更新文档”部分中的任何值也适用于新文档。您也可以使用$setOnInsert运算符指定您希望在“插入”时创建的字段,因为这些值仅在创建时使用。

事实上证明这是一个很好的办法就是做两个“UPSERT”操作如下:

db.test.update({ "a": "test" },{ "$set": { "b": "data" } },{ "upsert": true}); 
db.test.update({ "a": "test" },{ "b": "data" },{ "upsert": true}); 

没有任何更新运营商在这里你只是发送整个文件的第二次迭代。这意味着,当“插入”发生在你第一次有这样的文件:

{ "a": "test", "b": "data" } 

但是,当然,当你执行该文件与现场“一”等于“测试”相匹配的第二次更新,则生成的文档是这样的:

{ "b": "data" } 

这是清楚地演示了语句的查询部分未用于写入实际更新。所以这只发生在插入时,并且仅在与语句的更新文档部分中存在的更新运算符一起使用时才会发生。

+0

如果我们使用与原始值不同的_key值进行更新,那么该怎么办?var data = {0,'test2' a:1 }; – anhlc 2014-10-17 00:03:08

+0

@chianh然后你在更新部分指定你想要“更改”的值:'{“_key”:“test1},{”$ set“:{”_key“:”test2“,”a“:1} }'。查询文件是用于“匹配”的,仅适用于插入。无论您在更新文档中添加了什么内容,都会应用。你不能“覆盖”'_id'顺便说一句。 – 2014-10-17 00:11:35

+0

谢谢@尼尔。我还不够清楚:在这种情况下,_key = test1不存在,这会使插入_key = test2? – anhlc 2014-10-17 00:15:08