MongoDB - 匹配数组中的多个值

时间:2013-03-08 21:14:39

标签: mongodb find

我希望能够找到多个在数组中具有三个或更多匹配值的文档。让我们说以下文件:

   [{
       name: 'John',
       cars: [1, 2, 3, 4]
   },
   {
       name: 'Jane',
       cars: [1, 2, 3, 8]
   },
   {
       name: 'Smith',
       cars: [1, 8, 10]
   }]

我们希望在以下数组中找到至少包含三个值(在汽车中)的文档:

   [1, 2, 3, 4, 5, 6, 7]

结果将是:

   [{
       name: 'John',
       cars: [1, 2, 3, 4]
   },
   {
       name: 'Jane',
       cars: [1, 2, 3, 8]
   }]

任何人都知道如何实现这一目标?

4 个答案:

答案 0 :(得分:13)

您可以发出$in个查询,然后通过代码过滤所需数组中包含3个或更多条目的记录。 (这是一些samle python代码)

def dennisQuestion():
    permissibleCars = [1,2,3,4,5,6,7]
    cursor = db.collection.find({"cars": {"$in": permissibleCars}})
    for record in cursor:
       if len(set(permissible) & set(record["cars"]))) >= 3
          yield record

答案 1 :(得分:7)

这是一个很好的问题,我认为没有一种简单的方法可以使用MongoDB为您提供的常用运算符。但是我可以想到以下方法来实现这个目标:

<强> 1。新领域

在应用代码中计算此值,并将结果保存在文档的新字段中。

<强> 2。蛮力

db.Collection.find( { $or: [
    { cars: $all [ 1, 2, 3 ] },
    { cars: $all [ 2, 3, 4 ] },
    ... list out all 35 combinations
] } )

第3。使用$where

db.Collection.find( { cars: { $in: [1,2,3,4,5,6,7] }, $where: function() {
    var numMatches = 0;
    for (var i = 1; i <= 7; i++)
        if (this.cars.indexOf(i) > -1) numMatches++;
    return numMatches >= 3;
} } );

答案 2 :(得分:0)

当Mongo 4.0.3中的字符串所在的值时,我不得不稍微修改@Zaid Masud选项3:

db.Collection.find( { cars: { $in: ["s1", "s2", "s3" , "s4", "s5" , "s6" , "s7"] },
    $where: function() {
        var options = ["s1", "s2", "s3" , "s4", "s5" , "s6" , "s7"];
        var numMatches = 0;
        for (var i = 0; i < 7; i++)
            if (this.cars.indexOf(options[i]) > -1) 
                numMatches++;
        return numMatches >= 3;
    } 
} );

(发表评论似乎有点大)

答案 3 :(得分:0)

对于Mongo v4.4.1,此查询有效

[
  {
    $project: {
      name: 1,
      cars: 1,
      show: {
        $let: {
          vars: {
            "b": {
              $gte: [{$size: {$setIntersection: [ [1,2,3,4,5,6,7],"$cars"]}},3]
            }
          },
          in: "$$b"
        }
      }
    }
  },
  {
    $match: {
      show: true,
      
    }
  },
  {
    $project: {
      show: 0
    }
  }
]