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();
});

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);

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


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.


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 .


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.


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

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();
});

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 },
    );
}

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);

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.