Возвратите обновленную коллекцию с Mongoose
Я работаю с nodejs/express/mongoose/angularjs. Я хотел бы обновить коллекцию с именем "Списки", которая имеет несколько свойств, один из которых представляет собой массив элементов. В следующем коде я нажимаю новые элементы задачи в массиве items. Все работает нормально, однако функция обновления не отправляет обновленную коллекцию, тогда я должен выполнить другой запрос в базе данных. Есть ли более эффективный способ сделать это?
Код nodejs/express:
exports.addTaskToList = function(req, res) {
var listId = req.params.Id;
var taskId = req.params.TaskId;
Lists.update({_id: listId}, {$push: {items: taskId}}, {safe:true, upsert: true}, function(err, result){
if(err) {
console.log('Error updating todo list. ' + err);
}
else{
console.log(result + ' todo list entry updated - New task added');
Lists.findById(listId).populate('items').exec(function (err, updatedEntry) {
if (err) {
console.log('Unable to retrieve todo list entry.');
}
res.send(JSON.stringify(updatedEntry));
});
}
});
};
Кроме того, элементы массива представляют собой массив ObjectIds. Эти элементы находятся в отдельной схеме, поэтому в отдельной коллекции. Можно ли выталкивать весь объект, а не только его _id, чтобы не создавалась другая коллекция?
Ответы
Ответ 1
Метод обновления не возвращает обновленный документ:
Однако, если нам не нужен документ, возвращенный в нашем приложении, и просто хотите напрямую обновить свойство в базе данных, Обновление Model # подходит для нас.
Если вам нужно обновить и вернуть документ, рассмотрите один из следующих вариантов:
Традиционный подход:
Lists.findById(listId, function(err, list) {
if (err) {
...
} else {
list.items.push(taskId)
list.save(function(err, list) {
...
});
}
});
Более короткий подход:
Lists.findByIdAndUpdate(listId, {$push: {items: taskId}}, function(err, list) {
...
});
Ответ 2
используйте метод findOneAndUpdate() и в опции использования параметра запроса: { "new": true}
return this.sessionModel
.findOneAndUpdate({user_id: data.user_id}, {$set:{session_id: suuid}}, { "new": true})
.exec()
.then(data=>{
return {
sid: data.session_id
}
})
Ответ 3
Относительно вашего последнего вопроса:
Можно ли протолкнуть весь объект, а не только его _id, чтобы нет другой коллекции?
Ответ: да. Вы можете легко хранить субдокументы в документах с помощью документации Mongoose (здесь). Изменив свою схему немного, вы можете просто нажать весь объект объекта (а не только элемент _id
) в массив элементов, определенных в схеме списка. Но вам нужно будет изменить вашу схему, например:
var itemSchema = new Schema({
// Your Item schema goes here
task: 'string' // For example
});
var listSchema = new Schema({
// Your list schema goes here
listName: String, // For example...
items: [itemSchema] // Finally include an array of items
});
Добавляя объект item
к свойству items
списка, а затем сохраняя этот список, ваш новый элемент будет сохранен в коллекции List. Например,
var list = new List({
listName: "Things to do"
});
list.items.push({
task: "Mow the lawn"
});
list.save(function(error, result) {
if (error) // Handle error
console.log(result.list) // Will contain your item instance
});
Поэтому, когда вы загружаете свой список, свойство items
будет заполнено массивом элементов.
Это связано с тем, что элементы больше не будут сохраняться в отдельной коллекции. Он будет сохранен в коллекции списка как под-документ списка.