应执行db.collection.getindexes()确认weights字段存在且结构一致;权重仅对text字段生效,必须为正整数,且只影响$text查询的score评分。

确认权重是否真的被写入索引定义
执行 db.collection.getIndexes(),找到对应 text 索引,检查 weights 字段是否出现在输出中,且结构与你传入 createIndex() 时完全一致。
常见错误是误以为 {title: "text", content: "text"}, {weights: {title: 5}} 会让 content 权重为默认值 1——其实它确实就是 1,但你没在 weights 对象里显式声明 content,容易误判为“content 没被索引覆盖”。【必须显式写出所有参与 text 索引的字段,哪怕只给默认权重 1】
如果 getIndexes() 返回里压根没有 weights 键,说明 createIndex() 命令根本没生效,可能因语法错误、权限不足或集合不存在而静默失败。
验证查询是否触发了文本索引评分逻辑
权重只在 {$text: {$search: "xxx"}} 查询中起作用,普通 find({title: /xxx/}) 或聚合中 $match 使用正则/等值条件,【完全不读取 weights 配置】。
运行 db.collection.find({$text: {$search: "test"}}, {score: {$meta: "textScore"}}).sort({score: {$meta: "textScore"}}),观察返回文档的 score 值是否随字段匹配内容产生差异。若所有文档 score 都是 1.0,大概率是 default_language 设置错误导致分词失败,中文字段被整段丢弃。
用 explain("executionStats") 检查:executionStages.stage 必须是 TEXT,且 nReturned > 0;若 stage 是 COLLSCAN,说明索引根本没被选中——权重再高也没意义。
排查权重值本身的合法性
方法一:权重必须是正整数(1, 2, 5, 10),不能是小数、字符串或 null。MongoDB 不校验类型,但非法值会导致整个 weights 对象被忽略,回退到全部字段权重为 1。
方法二:非 text 类型字段写进 weights 会被静默忽略。例如 {title: "text", status: 1} 建索引,再配 {weights: {title: 5, status: 10}},status 的 10 完全无效,因为 status 没声明为 "text"。
方法三:权重是相对关系,不是绝对分数。{a: 10, b: 1} 和 {a: 100, b: 10} 实际排序效果几乎一样——重点看比值,不是数值本身大小。
检查索引重建是否真正完成
第一步:确认旧索引已删除。执行 db.collection.dropIndex("旧索引名"),返回 { "nIndexesWas": X, "ok": 1 } 且 X > 0 才算成功。
第二步:创建新索引时明确指定 name,避免名字冲突。例如:db.collection.createIndex({title: "text", content: "text"}, {weights: {title: 8, content: 2}, name: "text_title_content_weighted"})。
第三步:重建后立刻用 getIndexes() 核对 name 和 weights 是否同步。大集合重建可能耗时数分钟,在此期间旧索引仍存在,新权重未就绪。
注意:前台建索引会锁表,后台建索引(background: true)虽不阻塞读写,但重建期间索引不可用——这期间任何 $text 查询都走不了新权重。











