Search code examples
node.jsmongodbupsertmonk

Issue with a simple mongo/monk findAndModify query


Just a note I am fairly new to mongo and more notably very new to using node/js.

I'm trying to write a query to insert new documents or update already existing documents in my collection.

The proposed structure of the collection is:

{ _id: xxxxxxx, ip: "xxx.xxx.xxx.xxx:xxxxxx", date: "xx-xx-xx xxxx" }

Note that my intention is a store an fixed length int for the _id rather than the internal ObjectId (is this possible/considered bad practice?). The int is guaranteed to be unique and comes from another source.

var monk = require('monk');
var db = monk('localhost:27017/cgo_schedule');

var insertDocuments = function(db, match) {
    var db = db;
    var collection = db.get('cgo_schedule');
    collection.findAndModify(
      {
        "query": { "_id": match.matchId },
        "update": { "$set": { 
            "ip": match.ip,
            "date": match.date
            },
        "$setOnInsert": {
          "_id": match.matchId,
        }},
        "options": { "new": true, "upsert": true }
      },
      function(err,doc) {
        if (err) throw err;
        console.log( doc );
      }
  );
}

This doesn't work at all however. It doesn't insert anything to the database, but it also gives no errors, so I have no idea what I'm doing wrong.

The output (for console.log (doc)) is null.

What am I doing wrong?


Solution

  • The Monk docs aren't much help, but according to the source code, the options object must be provided as a separate parameter.

    So your call should look like this instead:

    collection.findAndModify(
        {
            "query": { "_id": match.matchId },
            "update": { 
                "$set": { 
                    "ip": match.ip, 
                    "date": match.date 
                }
            }
        },
        { "new": true, "upsert": true },
        function(err,doc) {
            if (err) throw err;
            console.log( doc );
        }
    );
    

    Note that I removed the $setOnInsert part as the _id is always included on insert with an upsert.