文本索引怎么建
文本索引为字符串字段建立词项表:写入时按语言规则做分词与词干化,查询时用 $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" | 相关度分数 | 排序与投影需同时出现才生效 |
中文等无空格语言的分词依赖空格与标点切分:整句中文检索命中效果有限,评估时要如实说明局限,或改用外部检索引擎与应用侧分词方案。
一个集合只有一个文本索引:想调整参与字段或权重必须删除重建,大集合重建期间检索能力会受影响,需安排窗口。