MongoDB中$match搭配$regex报错,如何筛选published为true的搜索结果
问题原因
报错的核心原因有两点:
$match是MongoDB聚合管道的阶段操作符,不能嵌套在单个字段的查询条件中使用published是文档顶级字段,不属于blogCover.title的子属性,你把它放在blogCover.title的查询对象中,MongoDB会误认为你要对字符串类型的blogCover.title执行$match操作,自然会抛出类型不兼容的错误。
正确修改方案
直接把published: true作为顶级过滤条件,和blogCover.title的正则查询条件平级放置即可:
TFBlog.find({ published: true, "blogCover.title": { $regex: searchfield, $options: 'i' // 注意:原写法的'$i'多了$符号,标准写法是不带$的'i' } }).then((docs) => { res.send(docs); });
替代实现方案
1. 聚合管道写法
如果后续需要扩展排序、分页、关联查询等逻辑,可以用聚合管道的$match阶段实现:
TFBlog.aggregate([ { $match: { published: true, "blogCover.title": { $regex: searchfield, $options: 'i' } } }, // 可扩展其他聚合阶段,比如按发布时间倒序:{ $sort: { publishTime: -1 } } // 可扩展分页:{ $skip: 0 }, { $limit: 10 } ]).then((docs) => { res.send(docs); });
2. 全文索引优化方案
如果博客数据量较大,正则查询性能较低时,可以给blogCover.title建立文本索引,用$text实现搜索,性能远高于普通正则查询:
首先在模型定义时添加文本索引(仅需执行一次):
TFBlogSchema.index({ "blogCover.title": "text" });
查询代码:
TFBlog.find({ published: true, $text: { $search: searchfield } }).then((docs) => { res.send(docs); });
内容的提问来源于stack exchange,提问作者Tejas Shirnalkar
相关产品推荐
相关产品推荐

