Создать новый идентификатор объекта в 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