必须先建text索引再用$text查询,否则报错;$text仅支持OR逻辑、无前缀/模糊匹配,字段须为string或string数组,多字段或通配符索引需单独createIndex,$search才支持高级文本检索。

直接回答:必须先建 text 索引,再用 $text 查询,否则报错 error: text index required;且 $text 只支持 OR 逻辑、不支持前缀/模糊匹配,别指望它替代正则。
创建 text 索引前必须确认字段类型
只有 string 或 string array 字段才能参与 text 索引。如果字段是数字、null、嵌套对象或缺失,MongoDB 会跳过该字段值(不报错但不索引)。
-
db.articles.createIndex({ title: "text", content: "text" })—— 多字段索引,所有字符串字段都会被分词 -
db.articles.createIndex({ "$**": "text" })—— 通配符索引,自动覆盖所有字符串字段,适合 schema 不固定的集合 - 不能混用其他索引类型:
{ title: "text", createdAt: 1 }是非法语法,text索引必须独占一个createIndex调用
$text 查询只接受纯空格分隔的关键词
$text 内部按空格和标点切词,不做 N-gram 或前缀分析。搜索 "mongo" 不会命中 "mongodb",除非你显式建了同义词词典(原生不支持)。
-
db.articles.find({ $text: { $search: "mongodb tutorial" } })→ 匹配含mongodbORtutorial的文档 -
db.articles.find({ $text: { $search: "mongodb -tutorial" } })→ 含mongodb但不含tutorial -
db.articles.find({ $text: { $search: "\"nosql database\"" } })→ 必须双引号包裹,且要求词序严格一致 - 不支持
*通配符:"mongo*"或"mongod?"会被当作字面量处理,不会展开
排序必须显式投影 + $meta,不能只靠 sort()
相关性分数不是文档固有字段,必须通过 $meta: "textScore" 投影出来,否则 sort({ score: { $meta: "textScore" } }) 会静默失效(返回无序结果)。
- 正确写法:
db.articles.find({ $text: { $search: "index" } }, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" } }) - 错误写法:
db.articles.find({ $text: { $search: "index" } }).sort({ score: 1 })——score字段根本不存在,排序无效 - 聚合管道中要用
$match阶段放$text,$sort阶段用{ score: { $meta: "textScore" } },不能在$project里伪造score
真正容易被忽略的是:MongoDB 6.0+ 已明确建议迁移到 $search 聚合阶段,它支持拼写纠错、同义词、语言权重、高亮等——$text 是遗留方案,仅适用于简单关键词 OR 检索,且不支持中文分词(默认用英文分析器)。


















