Mongodb - 如何查找包含某些关键字数组的记录

标签 mongodb

最近想在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/

相关文章:

database - MongoDB 按年份查找查询

javascript - Mongoose 保存在 async.each 中创建重复项

javascript - 如何使用mongoose从node js中的集合中获取数据

mongodb - Symfony 2.1 + @MongoDBUnique(字段 ="email") 不唯一

MongoDB - $setIntersection 与 $facet

mongodb - 如何在 MongoDB 中使用 $match

java - Mongo Java 驱动程序 3.6.1 - 如何将 json 数组结构化字符串解析为 BasicDBList

mongodb - 如何在 MongoDB 中进行内部连接?

node.js - NPM install 未安装所有组件,node-gyp 失败

node.js - 如何在TypeORM中使用订阅者?