Mongoose - создать документ, если он не существует, в противном случае update-return document в любом случае
Я ищу способ реорганизации части моего кода, чтобы быть короче и проще, но я не очень хорошо знаю Mongoose, и я не уверен, как действовать дальше.
Я пытаюсь проверить коллекцию на наличие документа и, если она не существует, создайте ее. Если он существует, мне нужно его обновить. В любом случае мне нужно получить доступ к содержимому документа после этого.
То, что мне удалось сделать до сих пор, - это запрос коллекции для конкретного документа, и если он не найден, создайте новый документ. Если он найден, я обновляю его (в настоящее время для этого используются даты как фиктивные данные). Оттуда я могу получить доступ к найденному документу из моей начальной операции find
или недавно сохраненного документа, и это работает, но должен быть лучший способ выполнить то, что мне нужно.
Вот мой рабочий код, не отвлекающий дополнительные функции.
var query = Model.find({
/* query */
}).lean().limit(1);
// Find the document
query.exec(function(error, result) {
if (error) { throw error; }
// If the document doesn't exist
if (!result.length) {
// Create a new one
var model = new Model(); //use the defaults in the schema
model.save(function(error) {
if (error) { throw error; }
// do something with the document here
});
}
// If the document does exist
else {
// Update it
var query = { /* query */ },
update = {},
options = {};
Model.update(query, update, options, function(error) {
if (error) { throw error; }
// do the same something with the document here
// in this case, using result[0] from the topmost query
});
}
});
Я просмотрел findOneAndUpdate
и другие связанные методы, но я не уверен, соответствуют ли они моему варианту использования или я понимаю, как правильно их использовать. Может ли кто-нибудь указать мне в правильном направлении?
(Возможно) Связанные вопросы:
Изменить
Я не натолкнулся на вопрос, указанный мной в моих поисках, но после рассмотрения ответов там я придумал это. Это, безусловно, красивее, на мой взгляд, и это работает, поэтому, если я не делаю что-то ужасно неправильно, я думаю, что мой вопрос, вероятно, может быть закрыт.
Я был бы признателен за любой дополнительный ввод моего решения.
// Setup stuff
var query = { /* query */ },
update = { expire: new Date() },
options = { upsert: true };
// Find the document
Model.findOneAndUpdate(query, update, options, function(error, result) {
if (!error) {
// If the document doesn't exist
if (!result) {
// Create it
result = new Model();
}
// Save the document
result.save(function(error) {
if (!error) {
// Do something with the document
} else {
throw error;
}
});
}
});
Ответы
Ответ 1
Вы ищете параметр параметра new
. Опция new
возвращает вновь созданный документ (если создается новый документ). Используйте его так:
var query = {},
update = { expire: new Date() },
options = { upsert: true, new: true, setDefaultsOnInsert: true };
// Find the document
Model.findOneAndUpdate(query, update, options, function(error, result) {
if (error) return;
// do something with the document
});
Так как upsert
создает документ, если не находит документ, вам не нужно создавать другой вручную.
Ответ 2
Поскольку вы хотите реорганизовать части своего кода, чтобы они были короче и проще,
- Используйте
async / await
- Используйте
.findOneAndUpdate()
, как указано в этом ответе
let query = { /* query */ };
let update = {expire: new Date()};
let options = {upsert: true, new: true, setDefaultsOnInsert: true};
let model = await Model.findOneAndUpdate(query, update, options);
Ответ 3
///This is simple example explaining findByIDAndUpdate from my code added with try catch block to catch errors
try{
const options = {
upsert: true,
new: true,
setDefaultsOnInsert: true
};
const query = {
$set: {
description: req.body.description,
title: req.body.title
}
};
const survey = await Survey.findByIdAndUpdate(
req.params.id,
query,
options
).populate("questions");
}catch(e){
console.log(e)
}