最近想在MongoDB中过滤掉包含某个关键字数组的记录,例如:我有5条包含关键字数组的记录:
{a:[1,2]}
{a:[1,3,8]}
{a:[1,2,5]}
{a:[3,5,1]}
{a:[4,5]}
如果我输入数组 [1,2,3,5]
进行搜索,那么我想得到:
{a:[1,2]}
{a:[1,2,5]}
{a:[3,5,1]}
每一个都是[1,2,3,5]
的子数组。
有什么想法吗?
请不要使用 where 子句(如果可能)。谢谢!
最佳答案
在 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 就会返回一个项目。
所以我们可以通过将确切的数组元素传递给 $in 来解决这个问题,例如,如果我们想找到与这些确切数组匹配的项目 {a:[1,2]} {a:[1,2,5] } 和 {a:[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
传递给 $in 来查找所有的 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 或谷歌搜索中找到很多不同的方法。
关于Mongodb - 如何查找包含某些关键字数组的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9249183/