首页/数据/NoSQL 速查/文本索引的创建细节
MongoDB99 条

文本索引的创建细节

文本索引为字符串字段建立词项表:可对多字段赋权重、指定 default_language;每个集合只能建一个文本索引。

NoSQL 速查数据更新于 2026-10-13

文本索引怎么建

文本索引为字符串字段建立词项表:写入时按语言规则做分词与词干化,查询时用 $text 做词项匹配。它可以同时覆盖多个字段并给各字段不同权重,也可以指定语言或关闭语言处理。每个集合只能有一个文本索引,因此字段与权重的规划要一次想清楚,改起来需要删除重建。

基本信息

创建db.c.createIndex({ title: "text", body: "text" }, { weights: { title: 10, body: 1 } })
查询db.c.find({ $text: { $search: "mongo timeout" } })
语言设置default_language 指定分词语言,"none" 关闭词干与停用词处理
排序按相关度排序需投影 textScore:{ score: { $meta: "textScore" } }
数量限制一个集合最多一个文本索引,删除重建成本高
搜索语法$search 支持 -词 排除与 "短语" 精确短语

典型使用场景

  • 站内全文检索:标题与正文建同一文本索引,标题权重更高
  • 日志与工单检索:按关键词定位问题描述,再叠加时间与状态过滤
  • 多语言内容:分别确认各语言的分词表现,必要时统一关闭语言处理
  • 相关度排序:用 textScore 排序,让命中权重高的文档排在前面
  • 与结构化条件组合:文本匹配负责关键词,索引字段负责收窄范围

创建与查询

创建与查询
// 一个集合只能有一个文本索引:字段与权重一起规划好
// 混合语言内容常用 default_language: "none",避免英文词干化误伤其他语言词项
db.articles.createIndex(
  { title: "text", body: "text" },
  { weights: { title: 10, body: 1 }, default_language: "none", name: "idx_article_text" }
)

// 关键词查询:多个词为或关系,-词 表示排除,"短语" 表示精确短语
// db.articles.find({ $text: { $search: "sharding -legacy" } })

// 按相关度排序:需要把 textScore 投影出来才能排序
// db.articles.find({ $text: { $search: "replica" } }, { score: { $meta: "textScore" } })
//   .sort({ score: { $meta: "textScore" } }).limit(20)

选项读法

选项 / 语法含义注意点
weights各字段的权重值越大影响越大,默认均为 1
default_language"none" 关闭词干与停用词处理混合语言内容优先考虑关闭
$search 多词词之间或关系不是短语匹配,词序不影响命中
"精确短语"双引号表示短语依赖词序,命中要求更严
-词排除包含该词的文档与前缀组合使用时注意语法形态
$meta: "textScore"相关度分数排序与投影需同时出现才生效
中文等无空格语言的分词依赖空格与标点切分:整句中文检索命中效果有限,评估时要如实说明局限,或改用外部检索引擎与应用侧分词方案。
一个集合只有一个文本索引:想调整参与字段或权重必须删除重建,大集合重建期间检索能力会受影响,需安排窗口。

易错点

  • 以为中文能像英文一样分词检索:整词整句匹配效果差,上线前必须用真实中文样本验证召回
  • 只给部分字段建了文本索引:查询里用 $text 只覆盖索引内字段,其他字段的关键词永远搜不到
  • 把 $text 与普通条件混用但顺序写反:应让结构化条件先收窄范围,文本匹配才不至于扫描过多候选
  • 需要按相关度排序却没投影 textScore:排序字段不存在,排序无效且不报错

数据来源与参考

  • MongoDB Manual: Text Indexes
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌