Có một số cách tiếp cận để thực hiện những gì bạn muốn, nó chỉ phụ thuộc vào phiên bản MongoDB của bạn. Chỉ cần gửi phản hồi của trình bao. Nội dung về cơ bản là biểu diễn JSON, không khó để dịch cho các thực thể DBObject trong Java hoặc JavaScript được thực thi trên máy chủ để điều đó thực sự không thay đổi.
Cách tiếp cận đầu tiên và nhanh nhất là với MongoDB 2.6 trở lên, nơi bạn nhận được các hoạt động thiết lập mới:
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 } }
])
Các toán tử mới có $ setIntersection
đang thực hiện công việc chính và cũng là $ kích thước
toán tử đo kích thước mảng và giúp lọc sau này. Điều này kết thúc như một so sánh cơ bản của các "tập hợp" để tìm các mục giao nhau.
Nếu bạn có phiên bản MongoDB cũ hơn thì điều này vẫn có thể thực hiện được, nhưng bạn cần thêm một vài giai đoạn nữa và điều này có thể ảnh hưởng phần nào đến hiệu suất tùy thuộc vào việc bạn có các mảng lớn:
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 }}
])
Hoặc nếu tất cả những điều đó dường như có liên quan hoặc các mảng của bạn đủ lớn để tạo ra sự khác biệt về hiệu suất thì luôn có 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 }
}
)
Lưu ý rằng trong mọi trường hợp, $ in
toán tử vẫn giúp bạn giảm kết quả mặc dù nó không phải là kết quả khớp đầy đủ. Yếu tố phổ biến khác là kiểm tra "kích thước" của kết quả giao nhau để giảm phản hồi.
Tất cả đều khá dễ dàng để viết mã, hãy thuyết phục ông chủ chuyển sang MongoDB 2.6 hoặc cao hơn nếu bạn chưa có ở đó để có kết quả tốt nhất.