Search code examples
node.jsmongodbmongoskin

How to check if Mongo's $addToSet was a duplicate or not


I am using Mongoskin + NodeJS to add new keywords to MongoDB. I want to notify the user that the entry was a duplicate but not sure how to do this.

/*
* POST to addkeyword.
*/
router.post('/addkeyword', function(req, res) {
var db = req.db;
db.collection('users').update({email:"[email protected]"}, {'$addToSet': req.body }, function(err, result) {
    if (err) throw err;
    if (!err) console.log('addToSet Keyword.' );
}); 
});

The result does not seem to be of any use since it doesn't state if the keyword was added or not.


Solution

  • At least in the shell you can differentiate if the document was modified or not (see nModified).

    > db.test4.update({_id:2}, {$addToSet: {tags: "xyz" }})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    
    > db.test4.update({_id:2}, {$addToSet: {tags: "xyz" }})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
    

    Update for Node

    When you use collection.update(criteria, update[[, options], callback]); you can retrieve the count of records that were modified.

    From the node docs

    callback is the callback to be run after the records are updated. Has two parameters, the first is an error object (if error occured), the second is the count of records that were modified.

    Another Update

    It seems at least in version 1.4.3 the native Mongo Node driver is not behaving as documented. It is possible to work around using the bulk API (introduced in Mongo 2.6):

    var col = db.collection('test');
    // Initialize the Ordered Batch
    var batch = col.initializeOrderedBulkOp();
    batch.find({a: 2}).upsert().updateOne({"$addToSet": {"tags": "newTag"}});
    // Execute the operations
    batch.execute(function(err, result) {
      if (err) throw err;
      console.log("nUpserted: ", result.nUpserted); 
      console.log("nInserted: ", result.nInserted); 
      console.log("nModified: ", result.nModified); // <- will tell if a value was added or not
      db.close();
    });