我有一个查找查询,它使用$in来检查指定的数组是否包含在集合字符串数组中:
db.Doc.find({ tags: { '$in': ['tag1','tag2'] } })
我正在重构此查询以使用聚合框架,但在$project
或$match
聚合阶段找不到等效的$match
比较操作符。
是否可以在聚合查询的$in
或$match
阶段使用$project
比较运算符。
发布于 2018-04-07 11:42:35
回答你的问题:是的,但不是你所期望的那样。在聚合查询的$in或$match阶段使用$project操作符是可能的,但每个阶段的用法和用途并不完全相同。
“相同”$in操作符有两种截然不同的类型(造成语义混淆):
{ $in: [ <needle expression>, <array haystack expression> ] }
,所有这条灰色线都变成了真或false (我使用了PHP文档的in_array指针-heystack语义来更好地解释)。因此,{ $in [ 'foo', [ 'foo', 'bar', 'baz' ] ] }
是真正的,因为foo在数组中。但是,在前面的非聚合$in中,{ maybeFooField: { $in: [ 'foo', 'bar', 'baz' ] } }
结构查询只是缩小了结果集,而不会导致布尔值为true或false。回到您的重构,问题是您的预期结果是什么?为什么从一开始就转向聚合框架?
如果只想缩小或过滤结果集,然后使用其他聚合计算,则使用简单的non-aggregational $in运算符。
db.Doc.aggregate([
{ $match: { tags: {$in: ['tag1','tag2'] } } } // non-aggregational $in
])
但是,如果要根据某些标记的存在与否添加信息,请使用aggregational $in运算符。
db.Doc.aggregate([
{ $project: { hasAnyTag: {$in: [$tags, ['tag1', 'tag2'] ] } } } // aggregational $in
])
注意,您有更多的聚合操作符可以处理数组,如:$setIntersection和$setIsSubset。
发布于 2018-04-07 08:44:18
查询: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
,这取决于是否匹配。
https://stackoverflow.com/questions/49705416
复制相似问题