admin管理员组文章数量:1327713
In my database, I have a field called 'fruits' which is a simple array. When inserting elements in this array, I use $addToSet
to only insert elements that do not exist already in this array.
I want to know whether or not the element I insert really modified this field. However, the docModified
parameter in the callback always returns 1 even when I try to add an element that already exists.
model.update (
{ username: username }, // find the document
{ $addToSet : { fruits: "apple" } }, // add "apple" to fruits field
function (err, docModified) {
console.log(docModified);
// !PROBLEM: this will print "1" no matter what
}
);
Does anyone know why? Thanks a lot! (btw I'm using Mongoose)
In my database, I have a field called 'fruits' which is a simple array. When inserting elements in this array, I use $addToSet
to only insert elements that do not exist already in this array.
I want to know whether or not the element I insert really modified this field. However, the docModified
parameter in the callback always returns 1 even when I try to add an element that already exists.
model.update (
{ username: username }, // find the document
{ $addToSet : { fruits: "apple" } }, // add "apple" to fruits field
function (err, docModified) {
console.log(docModified);
// !PROBLEM: this will print "1" no matter what
}
);
Does anyone know why? Thanks a lot! (btw I'm using Mongoose)
Share Improve this question edited Jun 27, 2017 at 8:33 Neil Lunn 151k36 gold badges355 silver badges325 bronze badges asked Jul 27, 2014 at 1:45 MariaMaria 3,5257 gold badges35 silver badges48 bronze badges2 Answers
Reset to default 6The current method implementations in mongoose use the legacy write concern API to determine the count of modified documents. As you note, even if there is no actual change to the content such as an $addToSet
operation that does not add a new member to the set, the modified count will be returned.
As long as your MongoDB server version is recent enough ( needs to be MongoDB 2.6 or greater ) and your mongoose version is recent enough an bundles a recent mongodb driver, then you can get the correct numbers from the Bulk Operations API responses.
To do this with mongoose you call the .collection
accessor on the model, which returns a native driver collection object:
var bulk = Model.collection.initializeOrderedBulkOp();
bulk.find({ username: username })
.updateOne({ $addToSet : { fruits: "apple" } });
bulk.execute(function(err,result) {
if (err) throw err;
console.log( JSON.stringify( result, undefined, 4 ) );
})
The "result" that is returned is an object conforming to the BulkWriteResult() specification, which more or less will look like this:
{
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 3,
"nModified" : 3,
"nRemoved" : 1,
"upserted" : [ ]
}
But specifically, where you use $addToSet
and the member already exists, the response will contain "nMatched": 1
and "nModified": 0
, which is the result you want to see, confirming that nothing was in fact added to the set.
In the MongoDB 2.6 shell, all of the update and insert methods try to use this API where it is available and only fallback to the legacy implementation when connecting to an older server. So If you did this in a modern shell with a modern server you would see the same results.
Hopefully mongoose itself will be altered to also use these methods where available and provide access to the same response. It seems to be the way of the future, but the codebase is yet to catch up and utilize this.
Note: The one thing to be careful of when using any of the native driver methods after accessing the collection object is to make sure that mongoose has an active connection to the database at the time this is called. Mongoose hides this by queuing up any request until a connection is actually established.
So if you are going straight to the collection object methods, then you might want to make sure you are waiting for the "open" event on the connection somewhere before that code executes.
"number affected is the number of docs updated, even if the new values are identical. this es straight from mongo." I got this from this forum post: https://github./LearnBoost/mongoose/issues/867
This means you'll have to e up with a different way to determine if the element was missing from the array before you update. I would remend pull all the documents and iterating through them before the update. Obviously it's not ideal, but i don't think there's any other way to do it.
Hope this helps.
本文标签: javascriptMongoDB incorrect update countStack Overflow
版权声明:本文标题:javascript - MongoDB: incorrect update count - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742214817a2434374.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论