Я видел это вопрос и ответ, но я не думал, что он действительно объяснил, что вы спросили, поэтому я подумал, что здесь что-то стоит.
Как показано в прилагаемой схеме, свойство «themes» является «ссылочным массивом», который в основном означает, что он будет содержать ссылку (или, по существу, значение ObjectId
), документ, который находится в другой коллекции , Определение схемы «мангуста» - это то, что связывает это с «ассоциированной» моделью, где этот объект находится, как вы должны знать.
Заданный вопрос: «Я нажимаю объект, или просто нажимаю значение _id
», что само по себе вызывает некоторые вопросы о том, «что вы действительно хотите здесь сделать?».
Для этого последнего, следующий пример кода (предполагая, модели и схемы все определены):
var project = new Project({ "name": "something" });
var topic = new Topic({ "name": "something" });
project.topics.push(topic); // this actually just adds _id since it's a ref
// More code to save topic and project in their colllections
Так, согласно комментарию в коде там, мангуст на самом деле только добавляет «_id» значение в родительский документ, даже если вы попросили его «нажать» весь «объект». Это просто работает, «это то, что вы хотели сделать» через представленный интерфейс схемы к модели. Не очень сложно сделать код, но просто вы понимаете основную механику.
Вы можете поочередно «использовать значение _id
» из созданного объекта (после его сохранения лучше всего для безопасности) и добавить его к массиву с помощью аналогичных средств.Это так же результат:
var project = new Project({ "name": "something" });
// Yes we saved the Project object, but later...
var topic = new Topic({ "name": "something" });
topic.save(function(err,topic) {
if (err) throw (err): // or better handling
project.topics.push(topic._id); // explicit _id
});
Этот метод все хорошо и прекрасно, при условии, конечно, что по той или иной форме вы на самом деле есть «объекты в памяти» на время обработки как для Project
и Topic
с соответствующими данными.
С другой стороны, предположим, что Project
представляет объект, который находится в коллекции, и хотя вы знаете, что это значение или другое «уникальное» представляющее свойство, данные объекта на самом деле не были загружены из базы данных через .findOne()
тип операции или аналогичный.
Предположим, что у вас нет данных модели Project
, которые хранятся в памяти. Итак, как добавить новую тему?
Это то, где действуют операторы MongoDB. В частности, есть $push
, который, конечно, аналогичен оператору массива .push()
в JavaScript, но с конкретным действием на стороне сервера.
Как уже говорилось ранее, не имеют модели данных Project
загружены, но вы хотите изменить конкретный Project
элемент в хранилище с помощью «толкая» нужный Topic
объект что-то определено в коллекции вашего Project
объекта по его идентификатор:
var topic = new Topic({ "name": "something" });
topic.save(function(err,topic) {
if (err) throw err; // or much better handling
Project.update(
{ "_id": projectId },
{ "$push": {
"topics": topic._id
}},
function(err,numAffected) {
// and handle responses here
}
);
})
«обновление» механика может быть .findOneAndUpdate()
или даже .findByIdAndUpdate()
, как вы считаете целесообразным (эти методы и вернуть доработанный объект по умолчанию, где .update()
не делает), что вы хотите достичь в результате вашей работы здесь.
Основное отличие от предыдущих подходов состоит в том, что, поскольку объект для Project
, который должен быть изменен, не находится в памяти для вашего кода приложения, то вы используете эти методы, чтобы просто изменить его на сервере. Это может быть «хорошей вещью», так как вам не нужно . Нужно «загрузить» эти данные, чтобы внести изменения. Операторы MongoDB разрешают вам $push
содержимое массива без загрузки в первую очередь.
Этот подход является вашим лучшим подходом к «параллельным обновлениям» с высокими транзакционными системами. Причина в том, что существует «нет гарантии», которая находится между .findOne()
или аналогичной операцией в вашем приложении и изменениями с действительным действием .save()
, которое «данные не были изменены» на сервере хранения между этими действиями.
Оператор $push
«гарантирует», что данные, измененные на сервере, остаются «как есть» на момент выполнения, конечно, с добавлением новых данных, которые вы добавили в массив.
Другое очевидное, что, поскольку операция использует собственный MongoDB-оператор для достижения этого эффекта, правила схемы мангуста распределяются. Таким образом, вы можете, конечно, не просто «толчок» вся «тема» объект в массив, без конечно, заканчивающийся с «всего» тема объекта в хранилище:
Project.update(
{ "_id": projectId },
{ "$push": {
"topics": topic // Oops, now that would store the whole object!
}},
function(err,numAffected) {
// and handle responses here
}
);
Это, по сути, разница между «, добавив, ссылку на объект "на массив и" добавление объекта к массиву ". Это зависит от используемых методов и методов «эффективности», которые вы на самом деле выбираете.
Надеюсь, это полезно для вас самих и для тех, кто может наткнуться на ту же тему, которую вы подняли.
Отличный ответ. Только то, что мне было нужно. Спасибо за разъяснения! –
Hi Kira. Не могли бы вы присоединиться к этой чатовой комнате? http://chat.stackoverflow.com/rooms/95345/ –
@BlakesSeven не могли бы вы выслать мне свой адрес электронной почты? Либо здесь, либо по электронной почте: [email protected] - Я хочу пригласить вас в команду MongoDB Slack, которую я создал. –