如何计算匹配的数组元素

Zha*_* Yi 2 mongodb mongodb-query aggregation-framework

我有一个集合,该集合中的每个文档都有一个数组字段countries.我想选择包含以下任何国家/地区的所有文件:

China, USA, Australia

输出应显示每个文档具有的上述国家/地区的数量.我使用下面的聚合命令:

db.movies.aggregate([
  {
    $match: { countries: { $in: ["USA", 'China', 'Australia'] } }
  },
  {
    $project: {
      countries: {$size: '$countries'}
    }
  }
]);
Run Code Online (Sandbox Code Playgroud)

它没有按预期工作.它显示了文档中具有上述国家/地区的所有国家/地区的数量.例如,如果一个文档China, Japan在其countries字段中,我希望它返回1(因为只有China在上面的国家/地区列表中),但它返回两个.我怎么能在聚合命令中做到这一点?

Nei*_*unn 6

$in包含的可能值的一个运营商只是"查询"文件,所以它不会删除阵列东西.

如果你想计算"只匹配",那么$setIntersection在之前应用于数组$size:

db.movies.aggregate([
  {
    $match: { countries: { $in: ["USA", 'China', 'Australia'] } }
  },
  {
    $project: {
      countries: {
        $size: { 
         "$setIntersection": [["USA", 'China', 'Australia'], '$countries' ] 
       }
    }
  }
]);
Run Code Online (Sandbox Code Playgroud)

这将"唯一"匹配的"集合"返回到针对文档中的数组提供的数组.

$in在现代版本中有一个替代的聚合运算符(至少MongoDB 3.4).在"测试"一个值的"奇异"值时,这有点不同.在数组比较中,您将应用于$filter:

db.movies.aggregate([
  {
    $match: { countries: { $in: ["USA", 'China', 'Australia'] } }
  },
  {
    $project: {
      countries: {
        $size: { 
         $filter: {
           input: '$countries',
           cond: { '$in': [ '$$this', ["USA", 'China', 'Australia'] ] }
         }
       }
    }
  }
]);
Run Code Online (Sandbox Code Playgroud)

对于"文档中"数组包含非唯一条目的数组,这真的应该对您很重要.即:

{ countries: [ "USA", "Japan", "USA" ] }
Run Code Online (Sandbox Code Playgroud)

你需要计算2"USA",而不是1这将是"套"的结果$setIntersection