Обновление встроенного документа Mongoose
У меня проблема со встроенным обновлением документа.
Мои определенные схемы:
var Talk = new Schema({
title: {
type: String,
required: true
},
content: {
type: String,
required: true
},
date: {
type: Date,
required: true
},
comments: {
type: [Comments],
required: false
},
vote: {
type: [VoteOptions],
required: false
},
});
var VoteOptions = new Schema({
option: {
type: String,
required: true
},
count: {
type: Number,
required: false
}
});
Теперь я хотел бы обновить vote.count++
с данными Talk
id и VoteOption
id. Для выполнения этой задачи у меня есть следующая функция:
function makeVote(req, res) {
Talk.findOne(req.params.id, function(err, talk) {
for (var i = 0; i < talk.vote.length; i++) {
if (talk.vote[i]._id == req.body.vote) {
talk.vote[i].count++;
}
}
talk.save(function(err) {
if (err) {
req.flash('error', 'Error: ' + err);
res.send('false');
} else {
res.send('true');
}
});
});
}
Все выполняется, я возвращаю res.send('true')
, но значение на счетчике не изменяется.
Когда я сделал несколько console.log
, я увидел, что он изменил значение, но talk.save
просто не сохраняет его в db.
Также я очень недоволен циклом, чтобы найти _id
встроенного документа. В документации для мангуста я читал о talk.vote.id(my_id)
, но это дает мне ошибку в отсутствии функции id
.
Ответы
Ответ 1
При обновлении типа Mixed
(который, как представляется, является чем-то другим, кроме базового типа, так что также включает вложенные документы), нужно называть .markModified
в документе. В этом случае это будет:
talk.markModified("vote"); // mention that `talk.vote` has been modified
talk.save(function(err) {
// ...
});
Надеюсь, это поможет кому-то в будущем, так как я не мог найти ответ очень быстро.
Ссылка:
... Mongoose теряет способность автоматически обнаруживать/сохранять эти изменения. Чтобы "сказать" Mongoose, что значение смешанного типа изменилось, вызовите метод .markModified(path)
документа, передающего путь к смешанному типу, который вы только что изменили.
Ответ 2
Это потому, что вы пытаетесь сохранить свой объект обсуждения до того, как обратный вызов, который увеличивает количество отсчетов, был запущен. Кроме того, вы убедились в том, чтобы создать экземпляр вашей схемы обсуждения? например:
var talk = new Talk();
Однако, если все, что вы хотите сделать, это увеличить вашу переменную count, mongo поддерживает атомарные обновления на месте, которые могут вам пригодиться:
talk.find( { _id : req.body.vote }, { $inc: { count : 1 } } );
взгляните на:
http://www.mongodb.org/display/DOCS/Updating#Updating-%24inc