MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Hapus Duplikat di mongodb

jika Anda siap untuk membuang semua duplikat lainnya, maka pada dasarnya Anda ingin .aggregate() untuk mengumpulkan dokumen dengan RegisterNumber yang sama nilai dan hapus semua dokumen lain selain kecocokan pertama.

MongoDB 3.0.x tidak memiliki beberapa pembantu modern tetapi dasar-dasar yang .aggregate() mengembalikan kursor untuk proses kumpulan hasil besar dan adanya "operasi massal" untuk performa tulis masih ada:

var bulk = db.collection.initializeOrderedBulkOp();
var count = 0;

db.collection.aggregate([
  // Group on unique value storing _id values to array and count 
  { "$group": {
    "_id": "$RegisterNumber",
    "ids": { "$push": "$_id" },
    "count": { "$sum": 1 }      
  }},
  // Only return things that matched more than once. i.e a duplicate
  { "$match": { "count": { "$gt": 1 } } }
]).forEach(function(doc) {
  var keep = doc.ids.shift();     // takes the first _id from the array

  bulk.find({ "_id": { "$in": doc.ids }}).remove(); // remove all remaining _id matches
  count++;

  if ( count % 500 == 0 ) {  // only actually write per 500 operations
      bulk.execute();
      bulk = db.collection.initializeOrderedBulkOp();  // re-init after execute
  }
});

// Clear any queued operations
if ( count % 500 != 0 )
    bulk.execute();

Dalam rilis yang lebih modern ( 3.2 ke atas ) lebih disukai menggunakan bulkWrite() alih-alih. Perhatikan bahwa ini adalah hal 'perpustakaan klien', karena metode "massal" yang sama yang ditunjukkan di atas sebenarnya disebut "di bawah tenda":

var ops = [];

db.collection.aggregate([
  { "$group": {
    "_id": "$RegisterNumber",
    "ids": { "$push": "$id" },
    "count": { "$sum": 1 }      
  }},
  { "$match": { "count": { "$gt": 1 } } }
]).forEach( doc => {

  var keep = doc.ids.shift();

  ops = [
    ...ops,
    {
      "deleteMany": { "filter": { "_id": { "$in": doc.ids } } }
    }
  ];

  if (ops.length >= 500) {
    db.collection.bulkWrite(ops);
    ops = [];
  }
});

if (ops.length > 0)
  db.collection.bulkWrite(ops);

Jadi $group menarik semuanya bersama-sama melalui $RegisterNumber nilai dan mengumpulkan dokumen yang cocok _id nilai ke array. Anda menghitung berapa kali ini terjadi menggunakan $sum .

Kemudian saring semua dokumen yang hanya memiliki hitungan 1 karena itu jelas bukan duplikat.

Melewati loop Anda menghapus kemunculan pertama _id dalam daftar yang dikumpulkan untuk kunci dengan .shift() , hanya menyisakan "duplikat" lainnya dalam larik.

Ini diteruskan ke operasi "hapus" dengan $in sebagai "daftar" dokumen untuk dicocokkan dan dihapus.

Prosesnya umumnya sama jika Anda memerlukan sesuatu yang lebih kompleks seperti menggabungkan detail dari dokumen duplikat lainnya, hanya saja Anda mungkin perlu lebih berhati-hati jika melakukan sesuatu seperti mengonversi kasus "kunci unik" dan karena itu benar-benar menghapus duplikat terlebih dahulu sebelum menulis perubahan pada dokumen yang akan dimodifikasi.

Bagaimanapun, agregasi akan menyoroti dokumen yang sebenarnya adalah "duplikat". Logika pemrosesan yang tersisa didasarkan pada apa pun yang sebenarnya ingin Anda lakukan dengan informasi tersebut setelah Anda mengidentifikasinya.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. mongodb:temukan ringkasan catatan

  2. Menghapus kunci/nilai dari entri MongoDB yang ada

  3. Bagaimana cara memanggil db.Collection.stats() dari driver Java Mongo

  4. Cara menghapus dokumen di dalam array di mongodb menggunakan $pull

  5. Otentikasi pengguna labu