Создать новый идентификатор объекта в mongoDB, используя узел js

Я использую приведенный ниже код для вставки данных в 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
        });
});

Этот код работает нормально, если я удаляю _id:new ObjectID().toHexString()

Здесь я хочу добиться того, чтобы к каждой новой истории я хотел, чтобы к ней был прикреплен уникальный объект _id

Что я делаю неправильно?

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

Это модель документа, _id, который я пытаюсь создать, предназначен для историй.

2 ответа

Решение

Вы не должны звонить .toHexString() на этом, как вы получите "строку", а не ObjectID. Строка занимает больше места, чем байты 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);
  }
)

Так что это прекрасно работает для меня. Здесь также отмечается "новая" опция, поэтому возвращается измененный документ, а не оригинальная форма документа, которая используется по умолчанию.

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

Однако здесь есть одна загвоздка, и это то, что если вы используете $addToSet и генерировать новый ObjectId для каждого элемента, то этот новый ObjectId делает все "уникальным". Таким образом, вы продолжаете добавлять вещи в "набор". Это также может быть $push если это то, что вы хотите сделать.

Так что если userId а также story в комбинации уже сделайте это "уникальным", а затем сделайте так:

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);
  }
)

Поэтому проверьте наличие уникальных элементов в массиве и их отсутствие, а затем добавьте их в массив. Также отметим, что вы не можете выполнить "неравенство" для элемента массива, смешивая с "upserts". Ваш тест для "подтверждения" документа должен быть только для основного значения "_id". Управление записями массива и "upserts" документа должны быть в отдельных операциях обновления. Не пытайтесь смешать их, в противном случае вы в конечном итоге создадите новые документы, когда вы не собирались это делать.

Кстати, вы можете сгенерировать ObjectID просто используя monk,

var db = monk(credentials.database);

var ObjectID = db.helper.id.ObjectID

console.log(ObjectID()) // generates an ObjectID
Другие вопросы по тегам