$ project,$ match或find()中的$ in运算符

时间:2018-04-07 08:25:11

标签: mongodb aggregation-framework

我有一个使用$ in的查询查询来检查指定的数组是否包含在集合字符串数组中:

72dpi

我正在重构此查询以使用聚合框架,但我无法在db.Doc.find({ tags: { '$in': ['tag1','tag2'] } })$in聚合阶段找到等效的$project比较运算符

是否可以在聚合查询的$match$in阶段使用$project比较运算符。

2 个答案:

答案 0 :(得分:1)

回答你的问题:是的,但并不像你期望的那样。可以在聚合查询的$ project或$ match阶段使用 $ in 运算符,但每个用法和目的都不相同。

有两种截然不同的类型"相同" $ in 运算符(造成语义混淆):

  1. 非聚合$in :通常会缩小搜索范围,例如过滤器。如果结果集不匹配,则无法向结果集添加信息。可以在find()收集方法和聚合内部使用(非常混乱的语义啊?)$match
  2. 聚合$in :通常会在结果集中添加布尔信息,可以在$cond中用作逻辑表达式,也可以在使用时删除一些结果$redact。可以在$project$addFields等中使用(但不能(!)在 find() $ match 中使用)。结构是:{ $in: [ <needle expression>, <array haystack expression> ] },所有这条灰线变为 true false (我使用了PHP&#39; s in_array needle -heystack语义更好地解释)。因此,{ $in [ 'foo', [ 'foo', 'bar', 'baz' ] ] } true 因为foo在数组中。 但是,在之前的非聚合 $ in 中,{ maybeFooField: { $in: [ 'foo', 'bar', 'baz' ] } }结构查询只会缩小结果集,并且它不会导致布尔值为true或false。
  3. 回到你的重构,问题是你的预期结果是什么?为什么从一开始就切换到聚合框架?

    如果您只想缩小或过滤掉结果集,然后使用其他一些聚合计算,请使用简单的非聚合 $ in 运算符。< / p>

    db.Doc.aggregate([
    { $match: { tags: {$in: ['tag1','tag2'] } } } // non-aggregational $in
    ])
    

    但是,如果您想根据某些标签的存在与否添加信息,请使用聚合 $ in 运算符。

    db.Doc.aggregate([
    { $project: { hasAnyTag: {$in: [$tags, ['tag1', 'tag2'] ] } } } // aggregational $in
    ])
    

    注意,您有更多聚合运算符可以使用数组,例如:$setIntersection$setIsSubset

答案 1 :(得分:0)

查询:db.Doc.find({ tags: { '$in': ['tag1','tag2'] } })相当于:

db.Doc.aggregate([
{$match:{tags: {$in: ['tag1','tag2'] }}}

])

当你在下面的投影中使用$in时:

db.Doc.aggregate([
{$project:{tags: {$in: ['tag1','tag2'] }}}

])

结果将是tags:truetags:false,具体取决于是否匹配。