1. ホーム
  2. javascript

[解決済み] Mongooseで文書を更新/アップサートするにはどうしたらいいですか?

2022-03-20 15:51:38

質問

時間のせいなのか、まばらなドキュメントに溺れ、Mongooseでの更新の概念を理解できていないせいなのか... :)

ここからが本題です。

私は連絡先のスキーマとモデル(短縮プロパティ)を持っています。

var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var mongooseTypes = require("mongoose-types"),
    useTimestamps = mongooseTypes.useTimestamps;


var ContactSchema = new Schema({
    phone: {
        type: String,
        index: {
            unique: true,
            dropDups: true
        }
    },
    status: {
        type: String,
        lowercase: true,
        trim: true,
        default: 'on'
    }
});
ContactSchema.plugin(useTimestamps);
var Contact = mongoose.model('Contact', ContactSchema);

私はクライアントから必要なフィールドを含むリクエストを受け取り、このように私のモデルを使用します。

mongoose.connect(connectionString);
var contact = new Contact({
    phone: request.phone,
    status: request.status
});

そして今、問題にたどり着いた。

  1. を呼び出すと contact.save(function(err){...}) 同じ電話番号のコンタクトがすでに存在する場合、エラーを受け取ります(予想通り - ユニーク)。
  2. を呼び出すことができません。 update() というメソッドがドキュメントに存在しないため、contact で使用されます。
  3. モデルでupdateを呼び出すと。
    Contact.update({phone:request.phone}, contact, {upsert: true}, function(err{...})
    Mongoose のアップデート実装は明らかにオブジェクトを2番目のパラメーターとして必要としていないので、ある種の無限ループに陥ってしまいます。
  4. 同じことをしても、2番目のパラメータにリクエストプロパティの連想配列を渡します。 {status: request.status, phone: request.phone ...} は動作しますが、特定の連絡先への参照がなく、その連絡先の createdAtupdatedAt プロパティを使用します。

というわけで、結局のところ、私が試した限りでは、あるドキュメントが与えられると contact 存在する場合はどのように更新し、存在しない場合はどのように追加するのでしょうか?

お忙しい中、ありがとうございました。

解決方法は?

さて、長い間待っても答えは出ませんでした。最終的に、更新/アップサートをあきらめ、次の方法をとりました。

ContactSchema.findOne({phone: request.phone}, function(err, contact) {
    if(!err) {
        if(!contact) {
            contact = new ContactSchema();
            contact.phone = request.phone;
        }
        contact.status = request.status;
        contact.save(function(err) {
            if(!err) {
                console.log("contact " + contact.phone + " created at " + contact.createdAt + " updated at " + contact.updatedAt);
            }
            else {
                console.log("Error: could not save contact " + contact.phone);
            }
        });
    }
});

うまくいくか?うん。私はこれで満足ですか?おそらくそうではないでしょう。1回のDB呼び出しの代わりに2回のDB呼び出し。
将来のマングース実装が、このような Model.upsert という関数があります。