$text 与文本索引
$text 是 MongoDB 内置的全文检索入口,依赖集合上的文本索引:建立索引时按语言规则切词、剔除停用词并生成词项表,$text 再用词项去匹配并给出相关度得分。查询支持空格分隔的词项、双引号包裹的短语与 - 前缀的排除词,投影出 $meta: "textScore" 后可据此排序。一个集合只允许一个文本索引,所以多个字段要合并建立,并用 weights 调整各字段权重。
基本信息
| 前提 | 集合上已建文本索引(text index) |
|---|---|
| 语法 | { $text: { $search: "词 -排除词" } } |
| 相关度 | 投影里放 $meta: "textScore",再用它排序 |
| 硬限制 | 每个集合只能有一个文本索引;$text 必须作为顶层条件 |
| 适用版本 | MongoDB 3.6+;中文无内置分词器 |
建索引与查询
建索引与查询
// 建索引:标题权重 10,正文权重 1
db.articles.createIndex({ title: "text", body: "text" }, { weights: { title: 10, body: 1 } })
// 词项检索:命中 分布式 或 事务,排除 mongodb
db.articles.find({ $text: { $search: "分布式 事务 -mongodb" } })
// 短语检索:双引号要求连续出现
db.articles.find({ $text: { $search: "\"分布式 事务\"" } })
// 按相关度排序:先投影出 score,再按同名字段排序
db.articles.find({ $text: { $search: "分布式" } }, { score: { $meta: "textScore" } })
.sort({ score: { $meta: "textScore" } })
// 核对文本索引字段与权重
db.articles.getIndexes()典型使用场景
- 站内文章检索:标题与正文联合搜索,按相关度排序
- 排除词过滤:检索结果里剔除无关品牌、测试数据
- 短语检索:要求多个词连续出现的合同条款、错误码检索
- 权重调优:标题命中比正文更重要时给 title 更高权重
- 检索叠加过滤:$text 与状态、时间区间等可索引条件并列写在同一层
检索语法要素
| 要素 | 写法 | 说明 |
|---|---|---|
| 多词 | 分布式 事务 | 默认任一命中(或关系),并给出相关度 |
| 短语 | "分布式 事务" | 要求连续出现 |
| 排除词 | -mongodb | 结果中不得包含该词 |
| 排序 | $meta: "textScore" | 必须与投影中的得分字段一起使用 |
文本索引的分词按语言规则进行,简体中文没有内置分词器,默认按空格与标点切分:整句自然语言检索命中率低。需要中文分词、同义词或复杂打分时应评估外部检索引擎。
文本索引需要随写入维护词项表,写入放大与内存占用都不可忽略,只在确实需要全文检索的字段上建。