最近我想过滤掉MongoDB中包含某个关键字数组的记录,例如:我有五个包含关键字数组的记录:
{a:[1,2]}
{a:[1,3,8]}
{a:[1,2,5]}
{a:[3,5,1]}
{a:[4,5]}
Run Code Online (Sandbox Code Playgroud)
如果我输入数组[1,2,3,5]进行搜索,那么我想得到:
{a:[1,2]}
{a:[1,2,5]}
{a:[3,5,1]}
Run Code Online (Sandbox Code Playgroud)
它们中的每一个都是子数组[1,2,3,5].
任何的想法?
请不要使用where子句(如果可能的话).谢谢!
它在mongodb中很简单,但更难的部分是为查询准备数据.让我在奥德解释一下
简单的部分
您可以使用它$in来查找数组中的匹配元素.让我们试试吧
db.coll.find({a:{$in:[1,2,3,5]})
Run Code Online (Sandbox Code Playgroud)
结果是
{ "_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 ] }
Run Code Online (Sandbox Code Playgroud)
哦,这不是我们预期的结果.是的,因为$返回一个项目,如果找到任何匹配元素(不一定全部).
所以我们可以通过将确切的数组元素传递给$ in来解决这个问题,例如,如果我们想要找到与这些精确数组相匹配的项{a:[1,2]} {a:[1,2,5]}和{一个:[4,5,6]}
db.coll.find({a:{$in:[[1,2],[1,2,5],[4,5,6]]}})
Run Code Online (Sandbox Code Playgroud)
你会得到
{ "_id" : ObjectId("4f37c41739ed13aa728e9efb"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f37c42c39ed13aa728e9efd"), "a" : [ 1, 2, 5 ] }
Run Code Online (Sandbox Code Playgroud)
就这样
最难的部分
真正最难的部分是形成输入数组的所有可能组合[1,2,3,5].您需要找到一种方法来获取源数组的所有组合(来自您的客户端)并将其传递给$ in.
例如,这个JS方法将为您提供给定数组的所有组合
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])
Run Code Online (Sandbox Code Playgroud)
会给你
[
[
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
]
]
Run Code Online (Sandbox Code Playgroud)
并且您可以将其传递arr给$ in以查找所有macthing元素
db.coll.find({a:{$in:arr}})
Run Code Online (Sandbox Code Playgroud)
会给你
{ "_id" : ObjectId("4f37c41739ed13aa728e9efb"), "a" : [ 1, 2 ] }
{ "_id" : ObjectId("4f37c42c39ed13aa728e9efd"), "a" : [ 1, 2, 5 ] }
Run Code Online (Sandbox Code Playgroud)
等等!,它仍然没有返回剩下的两个可能的项目.
因为好好看看arr,它只能找到组合.它会返回,[1,3,5]但文档中的数据是[3,5,1].所以很明显,$in按照给定的顺序检查项目(很奇怪!).
所以现在你了解它真的很难比较mongodb查询!您可以更改上面的JS组合前代码,找到每个组合的可能排列,并将其传递给mongodb $in.这就是诀窍.
由于您没有提及任何语言选择,因此很难推荐任何排列代码.但是你可以在Stackoverflow或谷歌搜索中找到很多不同的方法.
| 归档时间: |
|
| 查看次数: |
2678 次 |
| 最近记录: |