MongoDB条件聚合查询使用$in时出现聚合失败如何解决?
问题原因
你遇到的错误核心是混淆了MongoDB两种语境下的语法规则:
find()的查询过滤语境支持{字段名: {$in: [匹配项列表]}}的写法,且允许列表中混合正则和固定值- 聚合表达式语境(比如
$cond的if参数)不支持上述查询语法,且聚合操作符$in的作用、参数顺序、支持的匹配规则都和查询语境的$in不同:- 聚合
$in的语法是{$in: [待匹配值, 数组字段]},作用是判断前者是否存在于后者的数组中,无法用来判断字符串是否包含某个关键词、也不支持正则作为匹配项 - 聚合中要做正则匹配需要用
$regexMatch操作符
- 聚合
正确写法
如果你要实现和find查询完全一致的逻辑:匹配tweet字段完全等于coffee、或者匹配/tesla/i正则、或者匹配/rocket/正则的记录,写法如下:
db.Tweets.aggregate([ { $project: { _id: 0, tweet: 1, convert: { $cond: { if: { $or: [ // 匹配不区分大小写的tesla { $regexMatch: { input: "$tweet", regex: /tesla/i } }, // 匹配rocket { $regexMatch: { input: "$tweet", regex: /rocket/ } }, // 完全等于coffee { $eq: ["$tweet", "coffee"] } ] }, then: "contains words", else: "does not contain words" } } } } ])
如果你要判断的是tweet字段包含对应关键词(不需要完全等于coffee,只要字符串里有coffee就算匹配),把等值判断替换为正则匹配即可:
// 把{ $eq: ["$tweet", "coffee"] }替换为下面的写法 { $regexMatch: { input: "$tweet", regex: /coffee/ } }
注:$regexMatch是MongoDB 4.2及以上版本支持的操作符,如果你的版本低于4.2,可以用$indexOfBytes替代实现包含判断,示例:
// 判断包含tesla(区分大小写) { $gt: [{ $indexOfBytes: ["$tweet", "tesla"] }, -1] }
内容的提问来源于stack exchange,提问作者Christopher
相关产品推荐
相关产品推荐

