猫鼬确定update-upsert正在执行插入或更新 [英] mongoose to determine update-upsert is doing insert or update
问题描述
我想测试用于更新的"upsert"选项是否正常.因此,我使用相同的键两次将对象"upsert"到mongodb中.但是它没有显示插入的消息.我错过了什么吗?
I want to test if "upsert" option for updating is woking fine. So I "upsert" an object into mongodb twice with same key. However it didn't show inserted message. Was I missing something ?
(mongodb:v2.6.3;猫鼬:3.8.15)
(mongodb : v2.6.3; mongoose : 3.8.15)
Member.findOneAndRemove({user_id : 1},
function (err, doc) {
if (!err) onsole.log(doc ? 'deleted' : 'not found');
}); // -> deleted, make sure user_id = 1 doesn't exist
Member.update({user_id : 1},
{$set : {name:"name1"}},
{upsert : true, new : false}, // new : false, so that I can detect original doc is null then know it's a new one.
function (err, doc) {
if (!err) {
console.log(doc ? 'updated' : 'inserted')
}
}); // -> updated ? But it shoule be inserted, right ?
Member.update({user_id : 1},
{$set : {name:"name2"}},
{upsert : true, new : false},
function (err, doc) {
if (!err) {
console.log(doc ? 'updated' : 'inserted')
}
}); // -> updated, yes, no problem.
谢谢您的提示.
============答案============
============ answer =============
使用 .findOneAndUpdate 代替.update! 此外,请确保选项为{upsert:true, new:false }, 这样回调的第二个参数(doc)可以是原始文档,以防万一.
Use .findOneAndUpdate instead of .update ! Moreover, make sure option is {upsert: true, new : false}, so that the callback's 2nd parameter(doc) could be original document in case.
推荐答案
.update()
猫鼬中的方法将三个参数传递给回调,分别为err
,numAffected
和raw
响应.使用原始"对象查看发生了什么:
The .update()
method in mongoose takes three arguments to the callback, being err
, the numAffected
, and a raw
response. Use the "raw" object to see what happened:
Member.update({user_id : 1},
{$set : {name:"name1"}},
{upsert : true },
function (err, numAffected, raw) {
if (!err) {
console.log(raw)
}
});
您将看到这样的结构:
{ ok: true,
n: 1,
updatedExisting: false,
upserted: [ { index: 0, _id: 5456fc7738209001a6b5e1be } ] }
因此,创建的任何新文档中总是存在n
和'updatedExisting keys available, where the second is false on upserts and true otherwise.
upserted will contain the
_id`值.
So there is always the n
and 'updatedExistingkeys available, where the second is false on upserts and true otherwise.
upsertedwill contain the
_id` values of any new documents created.
对于n
或"numAffected",基本上是1,在旧版写关注响应下匹配了文档.
As for n
or the "numAffected", this is basically always 1 where a document was matched under the legacy write concern responses.
您可以使用Bulk Operations表单在MongoDB 2.6及更高版本中看到新的WriteResult响应:
You can see the new WriteResult response in MongoDB 2.6 and above using the Bulk Operations form:
var bulk = Member.collection.initializeOrderedBulkOp();
bulk.find({user_id : 1}.upsert().update({$set : {name:"name1"}});
bulk.execute(err,result) {
console.log( JSON.stringify( result, undefined, 2 ) );
}
在第一次迭代中,您将得到如下内容:
Which on a first iteration you get something like this:
{
"ok": 1,
"writeErrors": [],
"writeConcernErrors": [],
"nInserted": 0,
"nUpserted": 1,
"nMatched": 0,
"nModified": 0,
"nRemoved": 0,
"upserted": [
{
"index": 0,
"_id": "5456fff138209001a6b5e1c0"
}
]
}
第二秒钟具有相同的参数:
And a second with the same parameters like this:
{
"ok": 1,
"writeErrors": [],
"writeConcernErrors": [],
"nInserted": 0,
"nUpserted": 0,
"nMatched": 1,
"nModified": 0,
"nRemoved": 0,
"upserted": []
}
该文档仅在实际更改的地方才标记为已修改".
And the document would only be marked as "modified" where something was actually changed.
因此,无论如何,.update()
操作都不会返回修改后的文档或原始文档.这就是.findOneAndUpdate()
方法,它是执行原子操作的基本.findAndModify()
周围的猫鼬包装. .update()
方法通常用于批量操作,因此不会返回文档内容.
So at any rate, .update()
operations do not return the modified document or the original document. That is the .findOneAndUpdate()
method, a mongoose wrapper around the basic .findAndModify()
which performs an atomic operation. The .update()
methods are typically meant for bulk operations and as such do not return document content.
这篇关于猫鼬确定update-upsert正在执行插入或更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!