1. ホーム
  2. javascript

[解決済み] Mongoose - ドキュメントが存在しない場合は作成、そうでない場合は更新 - いずれの場合もドキュメントを返す

2023-04-21 22:55:12

質問

自分のコードの一部をより短くシンプルにリファクタリングする方法を探しているのですが、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;
            }
        });
    }
});

どのように解決するのですか?

あなたが探しているのは 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 はドキュメントが見つからなければドキュメントを作成するので、手動で別のドキュメントを作成する必要はありません。