create a new object Id in mongoDB using node js
Asked Answered
N

2

9

I am using the below code to insert data to mongodb

    router.post('/NewStory', function (req, res) {
var currentObject = { user: userId , story : story , _id:new ObjectID().toHexString() };
        req.db.get('clnTemple').findAndModify({
            query: { _id: req.body.postId },
            update: { $addToSet: { Stories: currentObject } },
            upsert: true
        });
});

This code is working fine if i remove the _id:new ObjectID().toHexString()

What i want to achieve here is that for every new story i want a unique _id object to be attached to it

What am i doing wrong?

{
    "_id": {
        "$oid": "55ae24016fb73f6ac7c2d640"
    },
    "Name": "some name",
     ...... some other details
    "Stories": [
        {
            "userId": "105304831528398207103",
            "story": "some story"
        },
        {
            "userId": "105304831528398207103",
            "story": "some story"
        }
    ]
}

This is the document model, the _id that i am trying to create is for the stories

Necrose answered 4/8, 2015 at 4:56 Comment(2)
you dont need to do this mongodb automatically create _id property as a uniqe idConah
where is this ObjectID initializedConah
C
12

You should not be calling .toHexString() on this as you would be getting a "string" and not an ObjectID. A string takes more space than the bytes of an ObjectId.

var async = require('async'),
    mongo = require('mongodb'),
    db = require('monk')('localhost/test'),
    ObjectID = mongo.ObjectID;


var coll = db.get('junk');

var obj = { "_id": new ObjectID(), "name": "Bill" };

coll.findAndModify(
  { "_id": new ObjectID() },
  { "$addToSet": { "stories": obj } },
  {
    "upsert": true,
    "new": true
  },
  function(err,doc) {
    if (err) throw err;
    console.log(doc);
  }
)

So that works perfectly for me. Noting the "new" option there as well so the modified document is returned, rather than the original form of the document which is the default.

 { _id: 55c04b5b52d0ec940694f819,
   stories: [ { _id: 55c04b5b52d0ec940694f818, name: 'Bill' } ] }

There is however a catch here, and that is that if you are using $addToSet and generating a new ObjectId for every item, then that new ObjectId makes everything "unique". So you would keep adding things into the "set". This may as well be $push if that is what you want to do.

So if userId and story in combination already make this "unique", then do this way instead:

coll.findAndModify(
  { 
      "_id": docId, 
      "stories": {
          "$not": { "$elemMatch": { "userId": userId, "story": story } }
      }
  },
  { "$push": { 
     "stories": {
         "userId": userId, "story": story, "_id": new ObjectID()
     }
  }},
  {
    "new": true
  },
  function(err,doc) {
    if (err) throw err;
    console.log(doc);
  }
)

So test for the presence of the unique elements in the array, and where they do not exist then append them to the array. Also noting there that you cannot do an "inequality match" on the array element while mixing with "upserts". Your test to "upsert" the document should be on the primary "_id" value only. Managing array entries and document "upserts" need to be in separate update operations. Do not try an mix the two, otherwise you will end up creating new documents when you did not intend to.

Covariance answered 4/8, 2015 at 5:35 Comment(4)
thanks I used the same code and it worked removed the async alone will it have any major impactNecrose
user id and story will not be making a unique key in my scenario as one user might add multiple storiesNecrose
@vignesh This is why I say "IF" that is the case. The thing to need to be aware of though is that by creating a "new" ObjectId value every time, then you are nullifying the need for $addToSet. By definition each "new" item added to the array is always then "unique".Covariance
is there a bug in Stackoverflow? I remember seeing around 4K points for @Blakes Seven and it is showing just 1 now?!Necrose
A
3

By the way, you can generate an ObjectID just using monk.

var db = monk(credentials.database);

var ObjectID = db.helper.id.ObjectID

console.log(ObjectID()) // generates an ObjectID
Atropine answered 9/11, 2015 at 20:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.