Подтвердить что ты не робот

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;
            }
        });
    }
});
4b9b3361

Ответ 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

Поскольку вы хотите реорганизовать части своего кода, чтобы они были короче и проще,

  1. Используйте async / await
  2. Используйте .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)
}