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.