我有一个使用$ in的查询查询来检查指定的数组是否包含在集合字符串数组中:
72dpi
我正在重构此查询以使用聚合框架,但我无法在db.Doc.find({ tags: { '$in': ['tag1','tag2'] } })
或$in
聚合阶段找到等效的$project
比较运算符
是否可以在聚合查询的$match
或$in
阶段使用$project
比较运算符。
答案 0 :(得分:1)
回答你的问题:是的,但并不像你期望的那样。可以在聚合查询的$ project或$ match阶段使用 $ in 运算符,但每个用法和目的都不相同。
有两种截然不同的类型"相同" $ in 运算符(造成语义混淆):
{ $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。回到你的重构,问题是你的预期结果是什么?为什么从一开始就切换到聚合框架?
如果您只想缩小或过滤掉结果集,然后使用其他一些聚合计算,请使用简单的非聚合 $ 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:true
或tags:false
,具体取决于是否匹配。