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

MongoDb :Temukan elemen umum dari dua array dalam kueri

Ada beberapa pendekatan untuk melakukan apa yang Anda inginkan, itu hanya tergantung pada versi MongoDB Anda. Hanya mengirimkan tanggapan shell. Isinya pada dasarnya adalah representasi JSON yang tidak sulit untuk diterjemahkan untuk entitas DBObject di Java, atau JavaScript untuk dieksekusi di server sehingga benar-benar tidak berubah.

Pendekatan pertama dan tercepat adalah dengan MongoDB 2.6 dan lebih tinggi di mana Anda mendapatkan set operasi baru:

var test = [ "t3", "t4", "t5" ];

db.collection.aggregate([
   { "$match": { "tags": {"$in": test } }},
   { "$project": {
       "tagMatch": {
           "$setIntersection": [
               "$tags",
               test
           ]
       },
       "sizeMatch": {
           "$size": {
               "$setIntersection": [
                   "$tags",
                   test
               ]
           }
       }
   }},
   { "$match": { "sizeMatch": { "$gte": 1 } } },
   { "$project": { "tagMatch": 1 } }
])

Operator baru di sana adalah $setIntersection yang melakukan pekerjaan utama dan juga $size operator yang mengukur ukuran array dan membantu pemfilteran terakhir. Ini berakhir sebagai perbandingan dasar "set" untuk menemukan item yang berpotongan.

Jika Anda memiliki versi MongoDB yang lebih lama, maka ini masih mungkin, tetapi Anda memerlukan beberapa tahapan lagi dan ini mungkin mempengaruhi kinerja, tergantung jika Anda memiliki array yang besar:

var test = [ "t3", "t4", "t5" ];

db.collection.aggregate([
   { "$match": { "tags": {"$in": test } }},
   { "$project": {
      "tags": 1,
      "match": { "$const": test }
   }},
   { "$unwind": "$tags" },
   { "$unwind": "$match" },
   { "$project": {
       "tags": 1,
       "matched": { "$eq": [ "$tags", "$match" ] }
   }},
   { "$match": { "matched": true }},
   { "$group": {
       "_id": "$_id",
       "tagMatch": { "$push": "$tags" },
       "count": { "$sum": 1 }
   }}
   { "$match": { "count": { "$gte": 1 } }},
   { "$project": { "tagMatch": 1 }}
])

Atau jika semua itu tampaknya terlibat atau array Anda cukup besar untuk membuat perbedaan kinerja maka selalu ada mapReduce :

var test = [ "t3", "t4", "t5" ];

db.collection.mapReduce(
    function () {
      var intersection = this.tags.filter(function(x){
          return ( test.indexOf( x ) != -1 );
      });
      if ( intersection.length > 0 ) 
          emit ( this._id, intersection );
   },
   function(){},
   {
       "query": { "tags": { "$in": test } },
       "scope": { "test": test },
       "output": { "inline": 1 }
   }
)

Perhatikan bahwa dalam semua kasus $in operator tetap membantu Anda untuk mengurangi hasil meskipun tidak sepenuhnya cocok. Elemen umum lainnya adalah memeriksa "ukuran" hasil persimpangan untuk mengurangi respons.

Semua cukup mudah untuk membuat kode, yakinkan bos untuk beralih ke MongoDB 2.6 atau lebih tinggi jika Anda belum melakukannya untuk hasil terbaik.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Operator titik tidak mengambil properti anak dari objek Dokumen Mongoose

  2. Skema MongoDB yang Benar untuk data agregat

  3. Mengapa saya mendapatkan luwak.koneksi tidak berfungsi saat mencoba terhubung dengan luwak?

  4. SCUMM:Infrastruktur Pemantauan Database Berbasis Agen di ClusterControl

  5. $addToSet ke array tetapi itu memberi saya null