创建文本索引前必须确认:目标字段为string类型;MongoDB版本≥2.6;大数据量时启用background:true避免阻塞写入。

创建文本索引前必须确认的三件事
MongoDB 的 $text 检索依赖文本索引,但不是所有字段都适合建——建错反而拖慢写入、浪费内存。先确认:
• 集合中目标字段确实是字符串类型(string),number 或 null 值会被跳过,不报错但查不到;
• 当前 MongoDB 版本 ≥ 2.6(旧版本不支持多字段或权重);
• 集合已有数据量较大时,建索引建议用 background: true,否则会阻塞写操作。
单字段、多字段与通配符索引怎么选
别一上来就用 { "$**": "text" }——它看似省事,实际隐患最多。
• db.posts.createIndex({ title: "text" }):适用于明确只搜标题的场景,索引小、更新快;
• db.posts.createIndex({ title: "text", content: "text", tags: "text" }):字段固定且都参与搜索时用,注意字段顺序不影响查询,但会影响索引大小(字符串越长、值越重复,索引膨胀越明显);
• db.posts.createIndex({ "$**": "text" }):仅推荐用于 schema 极度动态的集合(如用户自定义表单),但它会索引所有字符串字段(包括 _id、email 等非语义字段),导致索引体积暴增、停用词过滤失效、相关性评分失真。
中文全文检索必须绕开的坑
MongoDB 原生文本索引对中文支持极弱:默认按空格/标点分词,"人工智能" 会被切为单字或整个词,无法识别“机器学习”“AI”等同义变体。
• 不要依赖 language: "zh" 参数——它只调整停用词表,不解决分词问题;
• $text 查询对中文基本等价于模糊匹配,$search: "人工智能" 找不到“AI”或“机器学习”;
• 真实项目中,要么前置处理(应用层用 jieba 分词后存入 keywords 字段再建索引),要么直接切换到 Atlas Search 或 Elasticsearch;
• 如果坚持用原生方案,至少把高频术语预拆成数组存入独立字段,例如:{ keywords: ["人工智能", "AI", "machine learning"] },再对该字段建 { keywords: "text" } 索引。
查询时相关性排序和布尔逻辑的实际写法
$text 查询默认不排序,必须显式加 $meta: "textScore" 才能按匹配度排:db.posts.find({ $text: { $search: "mongodb tutorial" } }, { score: { $meta: "textScore" } }).sort({ score: { $meta: "textScore" } })
• 多词默认是 OR 关系,想 AND 必须加双引号:$search: '"mongodb" "tutorial"';
• 排除某词用减号:$search: "mongodb -video";
• 注意:权重(weights)只能在建索引时指定,建完不能改,比如希望 title 匹配比 content 更重:db.posts.createIndex({ title: "text", content: "text" }, { weights: { title: 10, content: 1 } })。


















