它在mongodb中很容易做到,但更難的部分是爲查詢準備數據。讓我來解釋一下,在奧德
簡單的零件
您可以使用$in
找到數組中的匹配元素。讓我們試着
db.coll.find({a:{$in:[1,2,3,5]})
,其結果是
{ "_id" : ObjectId("4f37c41739ed13aa728e9efb"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f37c42439ed13aa728e9efc"), "a" : [ 1, 3, 8 ] }
{ "_id" : ObjectId("4f37c42c39ed13aa728e9efd"), "a" : [ 1, 2, 5 ] }
{ "_id" : ObjectId("4f37c43439ed13aa728e9efe"), "a" : [ 3, 5, 1 ] }
{ "_id" : ObjectId("4f37c43e39ed13aa728e9eff"), "a" : [ 4, 5 ] }
喔,它不是我們所期望的結果。是的,因爲如果找到任何匹配元素(不一定全部),則返回一個項目。
所以我們可以通過將確切的數組元素傳遞給$ in來解決這個問題,例如,如果我們想找到匹配這些確切數組的項{a:[1,2]} {a:[1,2,5 ]}和{一:[4,5,6]}
db.coll.find({a:{$in:[[1,2],[1,2,5],[4,5,6]]}})
你會得到
{ "_id" : ObjectId("4f37c41739ed13aa728e9efb"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f37c42c39ed13aa728e9efd"), "a" : [ 1, 2, 5 ] }
這就是所有
最難的部分
真正最難的部分是形成你的輸入數組[1,2,3,5]的所有可能的組合。您需要找到一種方法來獲取源數組的所有組合(從您的客戶端)並將其傳遞給$ in。
例如,這JS method會給你所有給定陣列的
var combine = function(a) {
var fn = function(n, src, got, all) {
if (n == 0) {
if (got.length > 0) {
all[all.length] = got;
}
return;
}
for (var j = 0; j < src.length; j++) {
fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all);
}
return;
}
var all = [];
for (var i=0; i < a.length; i++) {
fn(i, a, [], all);
}
all.push(a);
return all;
}
>> arr= combine([1,2,3,5])
會給你
[
[
1
],
[
2
],
[
3
],
[
5
],
[
1,
2
],
[
1,
3
],
[
1,
5
],
[
2,
3
],
[
2,
5
],
[
3,
5
],
[
1,
2,
3
],
[
1,
2,
5
],
[
1,
3,
5
],
[
2,
3,
5
],
[
1,
2,
3,
5
]
]
組合,你可以通過這個arr
至$在找到所有macthing元素
db.coll.find({a:{$in:arr}})
會給你
{ "_id" : ObjectId("4f37c41739ed13aa728e9efb"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f37c42c39ed13aa728e9efd"), "a" : [ 1, 2, 5 ] }
等等!,它仍然沒有返回其餘兩個可能的項目。
因爲看看arr,它只能找到組合。它返回[1,3,5]
但文檔中的數據是[3,5,1]
。所以它清楚$in
檢查項目按給定的順序(奇怪!)。
所以,現在你明白它比較mongodb查詢真的很難!您可以更改上述JS組合的前代碼,以查找每個組合的可能排列並將其傳遞給mongodb $in
。這就是訣竅。
由於您沒有提及任何語言選擇,所以很難推薦任何置換代碼。但是你可以在Stackoverflow或Google上找到很多不同的方法。
你喜歡需要在js中爲此編寫一個自定義過濾器,然後將其用作查詢的一部分。 http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-JavascriptExpressionsand%7B%7B%24where%7D%7D – Travis 2012-02-12 16:31:18