mongodb upsert是否使用查询字段?

当使用upsert更新时,驱动程序将查询和$ set对象组合起来。

这里是一些示例代码

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

当我这样做,如果文件test1不存在,mongo似乎插入以下文件。

 { _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运算符指定要在“insert”中创build的查询部分中不存在的$setOnInsert ,因此这些值仅用于创build。

事实上,certificate这一点的一个好方法是做两个“upsert”操作,如下所示:

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

如果没有任何更新操作符,则只需在第二次迭代中发送整个文档。 这意味着当“插入”发生在第一个你有这样的文件:

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

但是,当然,当你执行第二次更新,匹配字段“a”等于“testing”的文件,那么生成的文件是这样的:

 { "b": "data" } 

这清楚地certificate了语句的查询部分不用于写入实际的更新。 所以这只会在插入时发生,并且只能在声明的更新文档部分中使用update操作符时使用