2017-10-21 162 views
0

我有一个集合,该集合中的每个文档都有一个数组字段countries。我要选择,其中包括以下任何国家的所有文件:如何计算匹配的数组元素

China, USA, Australia

和输出应显示上述国家每个文档都有数。 我使用aggregate命令如下:

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

预期这是行不通的。它显示了文件中具有上述国家/地区的所有国家/地区的数量。例如,如果某个文档的countries字段中有China, Japan,我预期它会返回1(因为只有China位于上述国家/地区列表中),但返回2。我怎么能在聚合命令中做到这一点?

回答

2

$in运算符只是“查询”包含其中一个可能值的文档,因此它不会从数组中删除任何内容。

如果要算“只匹配”,那么$size前应用$setIntersection到数组:

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

,返回的“独一无二”的“设置”匹配文档中提供了针对数组的数组。

$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'] ] } 
     } 
     } 
    } 
    } 
]); 

这确实应该只对你很重要,其中阵列“的文件中”包含的不是唯一的条目。即:

{ countries: [ "USA", "Japan", "USA" ] } 

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

+0

它的伟大工程,感谢结果。 –