Hapus kunci dari dokumen MongoDB menggunakan Mongoose

103

Saya menggunakan Perpustakaan Mongoose untuk mengakses MongoDB dengan node.js

Apakah ada cara untuk menghapus kunci dari dokumen ? yaitu tidak hanya mengatur nilainya menjadi nol, tetapi menghapusnya?

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();
});
Daniel Beardsley
sumber
1
Saya pikir saya telah menemukannya, tetapi setelah beberapa tes: mungkin tidak. Ini memiliki beberapa diskusi yang bagus tentang topik ini. groups.google.com/group/mongoose-orm/browse_thread/thread/…
Stephen
LOL tidak masalah, saya kira ini adalah posting Anda!
Stephen

Jawaban:

168

Pada versi awal, Anda perlu menurunkan driver node-mongodb-native. Setiap model memiliki objek koleksi yang berisi semua metode yang ditawarkan oleh node-mongodb-native. Jadi, Anda dapat melakukan tindakan yang dimaksud dengan ini:

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

Sejak versi 2.0, Anda dapat melakukan:

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

Dan sejak versi 2.4, jika Anda sudah memiliki contoh model, Anda dapat melakukan:

doc.field = undefined;
doc.save(callback);
staackuser2
sumber
Ini telah diperbaiki di Mongoose 2.X, jadi Anda dapat membiarkan koleksinya keluar.
staackuser2
4
Gunakan User.update({ _id: id }, { $unset: { field: 1 }}, callback)atau jika Anda memiliki contoh dokumen, setel jalur ke tidak terdefinisi dan kemudian simpan:doc.field = undefined; doc.save()
aaronheckmann
25
Hanya catatan bahwa jika Anda mencoba untuk menghapus properti lama yang tidak lagi ditentukan dalam skema Anda, Anda perlu melakukannyadoc.set('field', undefined)
evilcelery
3
bagaimana dengan menghapus doc.field.foo?
chovy
28
@evilcelery doc.set('field', undefined)mungkin tidak cukup karena mode ketat (default) tidak mengizinkan untuk menyetel bidang yang tidak lagi ada dalam skema. doc.set('field', undefined, { strict: false })bekerja dengan baik.
Alexander Link
56

Anda akan ingin melakukan ini:

User.findOne({}, function(err, user){
  user.key_to_delete = undefined;
  user.save();
});
deedubs
sumber
3
Itu hanya akan mengaturnya ke nol - bukan apa yang diminta OP.
Ian Henry
25
Mulai versi 2.4.0, menyetel kunci dokumen ke tidak ditentukan akan meneruskan $ unset ke mongodb aaronheckmann.posterous.com/mongoose-240
James Moore
30

Saya menggunakan luwak dan menggunakan salah satu fungsi di atas menurut saya. Fungsi mengkompilasi bebas dari kesalahan tetapi bidang tersebut akan tetap ada.

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

melakukan trik untuk saya.

Noushad
sumber
Mengupayakan jawaban yang berguna ini, sayang sekali @ alexander-link tidak membuatnya menjadi jawaban pada tahun 2015 ( stackoverflow.com/questions/4486926/… )
w00t
1
Terima kasih atas jawaban Anda, bagi saya, solusi lain tidak berfungsi untuk objek yang bersarang dalam array!
BenSower
@BenSower Ini juga kasus saya. Hanya solusi ini yang bekerja dengan baik karena saya harus menghapus bidang dengan larik setelah menemukan id dokumen tertentu
Luis Febro
Perhatikan bahwa string adalah jalur ke kunci. Jadi, jika objek yang ingin Anda hapus bersarang, Anda harus path ke sana. Jawaban ini memecahkan masalah saya!
Bradyo
8

Pada sintaks mongo untuk menghapus beberapa kunci, Anda perlu melakukan hal berikut:

{ $unset : { field : 1} }

Sepertinya di Mongoose sama saja.

Edit

Lihat contoh ini .

Andrew Orsich
sumber
Bisakah Anda memperjelas jawaban ini dan memberikan contoh kode yang berhubungan dengan contoh kode di atas?
Daniel Beardsley
maaf tapi saya tidak berpengalaman dengan luwak. Di atas sintaks adalah sintaks mongo, jadi saya kira driver untuk bahasa apa pun mendukung ini. Saya menemukan beberapa contoh, periksa di jawaban saya.
Andrew Orsich
1

Mungkinkah ini masalah sampingan seperti menggunakan

function (user)

dari pada

function(err, user)

untuk menemukan panggilan balik? Hanya mencoba membantu dengan ini karena saya sudah menangani kasusnya.

Luc
sumber
1

Dokumen Mongoose BUKAN objek javascript biasa dan itulah mengapa Anda tidak dapat menggunakan operator delete. (Atau unset dari pustaka 'lodash').

Opsi Anda adalah menyetel doc.path = null || undefined atau untuk menggunakan metode Document.toObject () untuk mengubah dokumen luwak menjadi objek biasa dan dari sana menggunakannya seperti biasa. Baca selengkapnya di luwak api-ref: http://mongoosejs.com/docs/api.html#document_Document-toObject

Contohnya akan terlihat seperti ini:

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

Mencoba:

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

  delete user.key_to_delete;

  user.save();
});
Jeisson Valderrama
sumber
0

Masalah dengan semua jawaban ini adalah bahwa mereka bekerja untuk satu bidang. sebagai contoh katakanlah saya ingin menghapus semua bidang dari Dokumen saya jika itu adalah string kosong "". Pertama Anda harus memeriksa apakah bidang adalah string kosong taruh ke $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 },
    );
}
Milad ranjbar
sumber
0

jika Anda ingin menghapus kunci dari koleksi coba metode ini. ini berhasil untuk saya

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

Anda dapat menggunakan delete user._doc.key

Joel Esperanza
sumber