Mongooseを使用してMongoDBドキュメントからキーを削除する


102

私はnode.jsでMongoDBにアクセスするためにMongooseライブラリを使用しています

ドキュメントからキー削除する方法はありますか?つまり、値をnullに設定するだけでなく、それを削除しますか?

User.findOne({}, function(err, user){
  //correctly sets the key to null... but it's still present in the document
  user.key_to_delete = null;

  // doesn't seem to have any effect
  delete user.key_to_delete;

  user.save();
});

1
私はそれを見つけたと思ったが、いくつかのテストの後、おそらく見つからなかった。しかし、これはこのトピックについていくつかの良い議論があります。groups.google.com/group/mongoose-orm/browse_thread/thread/...
スティーブン・

LOLは気にしません、これはあなたの投稿だったと思います!
Stephen

回答:


167

初期のバージョンでは、node-mongodb-nativeドライバーをドロップダウンする必要がありました。各モデルには、node-mongodb-nativeが提供するすべてのメソッドを含むコレクションオブジェクトがあります。だからあなたはこれで問題のアクションを行うことができます:

User.collection.update({_id: user._id}, {$unset: {field: 1 }});

バージョン2.0以降、次のことができます。

User.update({_id: user._id}, {$unset: {field: 1 }}, callback);

バージョン2.4以降、モデルのインスタンスがすでにある場合は、次のことができます。

doc.field = undefined;
doc.save(callback);

これはMongoose 2.Xで修正されたため、コレクションを省略できます。
staackuser2

4
使用するかUser.update({ _id: id }, { $unset: { field: 1 }}, callback)、またはドキュメントのインスタンスを持っている場合は、未定義し、それ保存するためにパスを設定しますdoc.field = undefined; doc.save()
aaronheckmann

25
スキーマで定義されなくなった古いプロパティを削除しようとしている場合は、削除する必要があることにdoc.set('field', undefined)
注意

3
削除についてはdoc.field.fooどうですか?
曲がりくねった14

28
doc.set('field', undefined)strictモード(デフォルト)ではスキーマにないフィールドを設定できないため、@ evilcelery では不十分な場合があります。doc.set('field', undefined, { strict: false })うまくいきました。
Alexander Link

56

あなたはこれをしたいと思うでしょう:

User.findOne({}, function(err, user){
  user.key_to_delete = undefined;
  user.save();
});

3
それは単にそれをnullに設定します-OPが求めているものではありません。
Ian Henry

25
バージョン2.4.0以降、ドキュメントキーをundefinedに設定すると、$ unsetがmongodbに渡さ
James Moore

30

私はマングースを使用し、上記の機能のいずれかを使用して要件を満たしました。関数はエラーなしでコンパイルされますが、フィールドはそのまま残ります。

user.set('key_to_delete', undefined, {strict: false} );

私のためにトリックをしました。


アレクサンダー・リンク@あまりにも悪いこの便利な答えを、Upvotingすると2015年には回答バック(作らなかったstackoverflow.com/questions/4486926/...
w00t

1
回答ありがとうございます。私にとって、他のソリューションは配列にネストされたオブジェクトに対しては機能しませんでした!
BenSower 2018年

@BenSowerこれも私のケースでした。特定のドキュメントのIDを見つけた後、配列を持つフィールドを削除しなければならなかったため、このソリューションのみがうまくいきました
Luis Febro

文字列はキーへのパスであることに注意してください。したがって、削除するオブジェクトがネストされている場合は、そのオブジェクトへのパスを指定する必要があります。この答えは私の問題を解決しました!
Bradyo

8

mongo構文で、いくつかのキーを削除するには、以下を実行する必要があります。

{ $unset : { field : 1} }

マングースにも同じように見えます。

編集する

この例を確認してください。


この答えを明確にして、上記のサンプルコードに関連するコード例を挙げていただけますか?
Daniel Beardsley、2011年

申し訳ありませんが、マングースは得意ではありません。上記の構文はmongo構文なので、どの言語のドライバーもこれをサポートしていると思います。私はいくつかの例を見つけました、私の答えでそれを確認してください。
Andrew Orsich、2011年

1

これは使用のような副次的な問題かもしれません

function (user)

の代わりに

function(err, user)

検索のコールバックのために?私はすでに事件があったので、これを手助けしようとしています。


1

MongooseドキュメントはプレーンなJavaScriptオブジェクトではないため、削除演算子を使用できません(または unset「lodash」ライブラリから)。

オプションはdoc.path = nullを設定することです|| undefinedまたはDocument.toObject()メソッドを使用してmongoose docをプレーンオブジェクトに変換し、そこから通常どおり使用します。mongoose api-refで詳細を読む:http : //mongoosejs.com/docs/api.html#document_Document-toObject

例は次のようになります。

User.findById(id, function(err, user) {
    if (err) return next(err);
    let userObject = user.toObject();
    // userObject is plain object
});

1

試してください:

User.findOne({}, function(err, user){
  // user.key_to_delete = null; X
  `user.key_to_delete = undefined;`

  delete user.key_to_delete;

  user.save();
});

0

これらすべての答えの問題は、それらが1つのフィールドで機能することです。たとえば、空の文字列の場合、すべてのフィールドをドキュメントから削除するとします""。まず、フィールドが空の文字列であるかどうかを確認する必要があります$unset

function unsetEmptyFields(updateData) {
  const $unset = {};
  Object.keys(updatedData).forEach((key) => {
    if (!updatedData[key]) {
      $unset[key] = 1;
      delete updatedData[key];
    }
  });
  updatedData.$unset = $unset;

  if (isEmpty(updatedData.$unset)) { delete updatedData.$unset; }

  return updatedData;
}

function updateUserModel(data){
const updatedData = UnsetEmptyFiled(data);

    const Id = "";
    User.findOneAndUpdate(
      { _id: Id },
      updatedData, { new: true },
    );
}

0

コレクションからキーを削除する場合は、このメソッドを試してください。これは私のために働いた

 db.getCollection('myDatabaseTestCollectionName').update({"FieldToDelete": {$exists: true}}, {$unset:{"FieldToDelete":1}}, false, true);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.