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

Apakah ada solusi untuk mengizinkan penggunaan regex di pipa agregasi Mongodb

Pertanyaan ini tampaknya datang berkali-kali tanpa solusi. Ada dua kemungkinan solusi yang saya tahu:solusi 1- menggunakan mapReduce. mapReduce adalah bentuk umum agregasi yang memungkinkan pengguna melakukan apa pun yang dapat dibayangkan dan diprogram.

berikut adalah solusi mongo shell menggunakan mapReduce Kami mempertimbangkan koleksi 'st' berikut.

{ "_id" : ObjectId("51d6d23b945770d6de5883f1"), "foo" : "foo1", "bar" : "bar1" }
{ "_id" : ObjectId("51d6d249945770d6de5883f2"), "foo" : "foo2", "bar" : "bar2" }
{ "_id" : ObjectId("51d6d25d945770d6de5883f3"), "foo" : "foo2", "bar" : "bar22" }
{ "_id" : ObjectId("51d6d28b945770d6de5883f4"), "foo" : "foo2", "bar" : "bar3" }
{ "_id" : ObjectId("51d6daf6945770d6de5883f5"), "foo" : "foo3", "bar" : "bar3" }
{ "_id" : ObjectId("51d6db03945770d6de5883f6"), "foo" : "foo4", "bar" : "bar24" }

kami ingin mengelompokkan berdasarkan foo, dan untuk setiap foo, hitung jumlah doc, serta jumlah doc dengan bar yang berisi substring 'bar2'.yaitu:

foo1: nbdoc=1, n_match = 0
foo2: nbdoc=3, n_match = 2
foo3: nbdoc=1, n_match = 0
foo4: nbdoc=1, n_match = 1

Untuk melakukannya, tentukan fungsi peta berikut

var mapFunction = function() {
  var key = this.foo;
  var nb_match_bar2 = 0;
  if( this.bar.match(/bar2/g) ){
    nb_match_bar2 = 1;
  }
  var value = {
    count: 1,
    nb_match: nb_match_bar2
  };

  emit( key, value );
};

dan fungsi pengurangan berikut

var reduceFunction = function(key, values) {

  var reducedObject = {
    count: 0,
    nb_match:0
  };
  values.forEach( function(value) {
    reducedObject.count += value.count;
    reducedObject.nb_match += value.nb_match;
  }
  );
  return reducedObject;
};

jalankan mapduce dan simpan hasilnya di koleksi map_reduce_result

db.st.mapReduce(mapFunction, reduceFunction, {out:'map_reduce_result'})
{
  "result" : "map_reduce_result",
  "timeMillis" : 7,
  "counts" : {
    "input" : 6,
    "emit" : 6,
    "reduce" : 1,
    "output" : 4
},
"ok" : 1,
}

Akhirnya, kita dapat menanyakan koleksi map_reduce_result, voila! solusinya

> db.map_reduce_result.find()
{ "_id" : "foo1", "value" : { "count" : 1, "nb_match" : 0 } }
{ "_id" : "foo2", "value" : { "count" : 3, "nb_match" : 2 } }
{ "_id" : "foo3", "value" : { "count" : 1, "nb_match" : 0 } }
{ "_id" : "foo4", "value" : { "count" : 1, "nb_match" : 1 } }

solusi 2- menggunakan dua agregasi dan penggabungan terpisahSaya tidak akan memberikan detail untuk solusi ini karena setiap pengguna mongo dapat dengan mudah melakukannya. Langkah 1:lakukan agregasi, abaikan bagian yang memerlukan regex untuk menjumlahkan. Langkah 2:lakukan pengelompokan agregasi kedua pada kunci yang sama dengan salah satu langkah pertama.tahap 1 dari pipeline:cocokkan ekspresi reguler;tahap 2:kelompokkan pada kunci yang sama seperti pada langkah pertama dan hitung jumlah dokumen di setiap grup {$sum:1};langkah 3:gabungkan hasil langkah 1 dan 2:untuk setiap kunci yang muncul di kedua hasil tambahkan bidang baru, jika kunci tidak ada di hasil kedua setel kunci baru ke 0.

Voila! solusi lain.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Kueri tanggal berfungsi dengan _id tetapi tidak dengan nilai Tanggal - MongoDB

  2. 'process.nextTick(function() { throw err; })' - Tidak terdefinisi bukan fungsi (mongodb/luwak)

  3. Cara mendapatkan data dari mongodb antara memasukkan dua hari di mongodb menggunakan luwak

  4. AJAX panggilan ke/dari contoh MongoDB untuk Node/Express?

  5. Implementasi pengindeksan internal MongoDB?