--- title: "ID 字段 fielddata 启用配置" date: 2026-02-20 lastmod: 2026-02-20 description: "indices.id_field_data.enabled 配置项用于控制是否允许在 _id 字段上加载 fielddata。" tags: ["字段数据", "ID字段", "fielddata", "已弃用"] summary: "配置项作用 # indices.id_field_data.enabled 配置项用于控制是否允许在文档的 _id 字段上加载 fielddata(字段数据)。 当启用时,可以对 _id 字段进行排序和聚合操作;禁用后会阻止在 _id 字段上的 fielddata 访问。 配置项属性 # 配置路径: indices.id_field_data.enabled 数据类型: Boolean(布尔值) 默认值: true 是否可选: 是 作用域: NodeScope(节点级别) 动态更新: 是(支持动态更新) 弃用状态: ⚠️ 此功能已被标记为弃用 配置项详解 # 工作机制 # _id 字段 fielddata 访问 enabled = true (默认): 查询包含 _id 排序 │ ↓ 加载 _id 字段的 fielddata ✅ │ ↓ 执行排序操作 │ ↓ 返回结果 enabled = false: 查询包含 _id 排序 │ ↓ 尝试加载 fielddata ❌ │ ↓ 抛出异常: "Fielddata access on the _id field is disallowed, you can re-enable it by updating the dynamic cluster setting: indices." --- ## 配置项作用 `indices.id_field_data.enabled` 配置项用于控制**是否允许在文档的 `_id` 字段上加载 fielddata(字段数据)**。 当启用时,可以对 `_id` 字段进行排序和聚合操作;禁用后会阻止在 `_id` 字段上的 fielddata 访问。 ## 配置项属性 - **配置路径**: `indices.id_field_data.enabled` - **数据类型**: `Boolean`(布尔值) - **默认值**: `true` - **是否可选**: 是 - **作用域**: NodeScope(节点级别) - **动态更新**: 是(支持动态更新) - **弃用状态**: ⚠️ **此功能已被标记为弃用** ## 配置项详解 ## 工作机制 ``` _id 字段 fielddata 访问 enabled = true (默认): 查询包含 _id 排序 │ ↓ 加载 _id 字段的 fielddata ✅ │ ↓ 执行排序操作 │ ↓ 返回结果 enabled = false: 查询包含 _id 排序 │ ↓ 尝试加载 fielddata ❌ │ ↓ 抛出异常: "Fielddata access on the _id field is disallowed, you can re-enable it by updating the dynamic cluster setting: indices.id_field_data.enabled" ``` ## 弃用说明 ``` 弃用背景 _id 字段 fielddata 已被弃用的原因: 1. 内存开销 - fielddata 加载需要额外内存 - _id 字段对所有查询都存在 - 大量查询会累积内存消耗 2. 性能影响 - 加载 fielddata 有性能开销 - 影响 JVM 堆内存使用 3. 更好的替代方案 - 将 _id 值复制到文档字段 - 使用 doc_values 而不是 fielddata - 性能更好,内存使用更可控 ``` ## 替代方案 ``` 推荐的替代实现 旧方式 (已弃用): { "_id": "doc123", "_source": { "title": "Example" } } 对 _id 排序: 需要 fielddata ❌ 新方式 (推荐): { "_id": "doc123", "_source": { "title": "Example", "id_field": "doc123" # 复制 _id 值 }, "id_field": { "type": "keyword", "doc_values": true } } 对 id_field 排序: 使用 doc_values ✅ ``` ## 配置建议 ## ⚠️ 重要提示 此配置项**已被标记为弃用**,建议使用替代方案。 ## 保持启用(默认) ```yaml indices: id_field_data: enabled: true # 默认值 ``` **建议**: 仅在旧代码迁移期间使用。新项目应使用替代方案。 ## 禁用 fielddata ```yaml indices: id_field_data: enabled: false # 禁用 ``` **建议**: 新项目应该禁用,使用替代方案。 ## 代码示例 ## easysearch.yml 基础配置 ```yaml indices: id_field_data: enabled: true ``` ## 禁用配置 ```yaml indices: id_field_data: enabled: false ``` ## 动态更新配置 ```json PUT /_cluster/settings { "transient": { "indices.id_field_data.enabled": false } } ``` ## 推荐的替代实现 ```json PUT /my_index { "mappings": { "properties": { "id_field": { "type": "keyword", "doc_values": true } } } } ``` ```json POST /my_index/_doc { "title": "Example", "id_field": "doc123" } ``` ## 使用场景 ## 推荐禁用的场景 - **新项目**: 所有新项目应该禁用 - **性能优化**: 希望减少内存使用 - **最佳实践**: 遵循官方推荐的替代方案 ## 临时保持启用的场景 - **旧代码迁移**: 正在从旧代码迁移 - **兼容性需要**: 需要与旧版本兼容 - **测试验证**: 测试环境中验证功能 ## 性能影响分析 ``` 内存使用对比 使用 fielddata: 查询 1: 加载 _id fielddata 内存: +10MB 查询 2: 加载 _id fielddata 内存: +10MB 查询 3: 加载 _id fielddata 内存: +10MB 总内存: 30MB ❌ 使用 doc_values: 索引时: 写入 doc_values 内存: +5MB (一次性) 查询 1, 2, 3: 读取 doc_values 内存: 几乎无增加 ✅ 总内存: 约 5MB ``` ## 弃用迁移 ``` 从 fielddata 迁移到 doc_values 步骤 1: 添加新字段 PUT /_template/template_name { "mappings": { "properties": { "id_field": { "type": "keyword", "doc_values": true } } } } 步骤 2: 修改索引代码 // 旧代码 .sort("_id") // 新代码 .sort("id_field") 步骤 3: 更新数据 POST /_update_by_query { "query": { "match_all": {} }, "script": { "source": "ctx._source.id_field = ctx._id" } } 步骤 4: 验证功能 测试新字段功能 确认排序和聚合正常 禁用 fielddata ``` ## 错误处理 ``` 禁用 fielddata 后的错误 错误信息: "Fielddata access on the _id field is disallowed" 原因: 1. 配置 enabled = false 2. 查询尝试访问 _id 的 fielddata 解决方案: 方案 1: 使用替代字段 - 使用 id_field 字段代替 - 确保索引映射正确 方案 2: 启用配置(不推荐) - 临时启用 id_field_data.enabled - 长期应该迁移到替代方案 方案 3: 修改查询逻辑 - 移除对 _id 的排序/聚合 - 使用其他字段 ``` ## 注意事项 1. **已弃用**: 此功能已被标记为弃用,不应在新代码中使用。 2. **默认启用**: 默认值为 `true`,保持向后兼容。 3. **替代方案**: 官方推荐使用 doc_values 替代。 4. **动态更新**: 支持动态更新,修改后立即生效。 5. **内存考虑**: 禁用可以减少内存使用。 6. **性能影响**: doc_values 性能比 fielddata 更好。 7. **规划迁移**: 建议规划迁移到替代方案。 8. **索引映射**: 替代字段需要添加到索引映射中。 9. **数据更新**: 需要更新现有文档以包含替代字段。 10. **测试验证**: 迁移后需要测试所有相关功能。