--- title: "路由缺失异常 (routing_missing_exception) 错误排查与解决" date: 2026-01-24 lastmod: 2026-01-24 description: "routing_missing_exception 表示执行操作时缺少必需的路由信息,需要在请求中添加路由参数或在映射中配置路由。" tags: ["路由", "分片路由"] summary: "为什么这个错误发生 # routing_missing_exception 表示执行操作时缺少必需的路由信息。路由(routing)值用于确定文档存储在哪个分片上,某些操作需要明确指定路由值。 这个错误可能由以下原因引起: 缺少路由参数:请求中未提供必需的路由值 自定义路由映射:索引配置了自定义路由映射 父文档关系:使用父子关系时需要路由值 分片路由:操作需要特定分片但未提供路由 客户端配置错误:客户端未正确配置路由 默认路由不适用:默认路由机制不适用于该操作 如何修复这个错误 # 1. 提供路由值 # # 在请求中添加路由参数 GET /<index>/_doc/<id>?routing=<routing_value> POST /<index>/_doc/<id>?routing=<routing_value> { "field": "value" } 2. 使用文档 ID 作为路由 # # 如果文档 ID 与路由值相同,可以设置默认路由 PUT /<index>/_mapping { "settings": { "index.routing.allocation.include._tier_preference": "data_hot" } } 3. 配置映射中的路由 # # 在索引创建时配置路由 PUT /<index> { "mappings": { "_routing": { "required": true } } } 4. 查看映射配置 # # 查看索引的路由配置 GET /<index>/_mapping?" --- ## 为什么这个错误发生 `routing_missing_exception` 表示执行操作时缺少必需的路由信息。路由(routing)值用于确定文档存储在哪个分片上,某些操作需要明确指定路由值。 这个错误可能由以下原因引起: 1. **缺少路由参数**:请求中未提供必需的路由值 2. **自定义路由映射**:索引配置了自定义路由映射 3. **父文档关系**:使用父子关系时需要路由值 4. **分片路由**:操作需要特定分片但未提供路由 5. **客户端配置错误**:客户端未正确配置路由 6. **默认路由不适用**:默认路由机制不适用于该操作 ## 如何修复这个错误 ### 1. 提供路由值 ```bash # 在请求中添加路由参数 GET //_doc/?routing= POST //_doc/?routing= { "field": "value" } ``` ### 2. 使用文档 ID 作为路由 ```bash # 如果文档 ID 与路由值相同,可以设置默认路由 PUT //_mapping { "settings": { "index.routing.allocation.include._tier_preference": "data_hot" } } ``` ### 3. 配置映射中的路由 ```bash # 在索引创建时配置路由 PUT / { "mappings": { "_routing": { "required": true } } } ``` ### 4. 查看映射配置 ```bash # 查看索引的路由配置 GET //_mapping?filter_path=**._routing # 查看所有设置 GET //_settings ``` ### 5. 更新客户端配置 ```java // 在客户端配置路由 IndexRequest request = new IndexRequest(""); request.id(""); request.routing(""); request.source(...); ``` ### 6. 使用批量 API 时提供路由 ```bash # 批量操作时为每个文档指定路由 POST /_bulk { "index": { "_index": "", "_id": "1", "routing": "user1" } } { "field": "value1" } { "index": { "_index": "", "_id": "2", "routing": "user2" } } { "field": "value2" } ``` ### 7. 父子文档路由 ```bash # 对于父子关系,使用父文档 ID 作为路由 POST //_doc/?routing= { "join": { "name": "child", "parent": "" }, "field": "value" } ``` ### 8. 搜索时使用路由 ```bash # 搜索时指定路由以提高性能 GET //_search?routing= { "query": { "match": { "field": "value" } } } ``` ### 9. 删除时提供路由 ```bash # 删除文档时需要路由值 DELETE //_doc/?routing= # 或通过查询删除 POST //_delete_by_query?routing= { "query": { "term": { "field": "value" } } } ``` ### 10. 更新时提供路由 ```bash # 更新文档时需要路由值 POST //_update/?routing= { "doc": { "field": "new_value" } } ``` ### 11. 配置默认路由 ```bash # 可以配置一个字段作为默认路由 PUT / { "mappings": { "_routing": { "required": true, "path": "user_id" } } } ``` ### 12. 批量导入时处理路由 ```java // 批量导入时为每个文档生成路由 BulkRequest bulkRequest = new BulkRequest(); for (Document doc : documents) { IndexRequest indexRequest = new IndexRequest(""); indexRequest.id(doc.getId()); indexRequest.routing(doc.getUserId()); // 使用用户 ID 作为路由 indexRequest.source(doc.toJson()); bulkRequest.add(indexRequest); } ``` ### 13. 验证路由配置 ```bash # 确认路由配置正确 GET //_mapping?filter_path=**.mappings._routing # 检查是否必需 GET //_mapping?filter_path=**.mappings._routing.required ``` ### 14. 搜索多个路由值 ```bash # 可以指定多个路由值 GET //_search?routing=value1,value2,value3 { "query": { "match_all": {} } } ``` ### 15. 使用别名处理路由 ```bash # 创建包含路由值的别名 POST /_aliases { "actions": [ { "add": { "index": "", "alias": "_alias", "routing": "routing_value" } } ] } ``` ### 预防措施 - 在索引创建时明确路由要求 - 在客户端代码中配置默认路由 - 为父子关系使用正确的路由 - 在批量操作中包含路由值 - 文档化路由配置 - 使用有意义的路由值 - 监控路由缺失错误 - 实现客户端验证 - 使用映射中的路由路径 - 测试所有操作的配置