配置项作用 #
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 ✅
配置建议 #
⚠️ 重要提示 #
此配置项已被标记为弃用,建议使用替代方案。
保持启用(默认) #
indices:
id_field_data:
enabled: true # 默认值
建议: 仅在旧代码迁移期间使用。新项目应使用替代方案。
禁用 fielddata #
indices:
id_field_data:
enabled: false # 禁用
建议: 新项目应该禁用,使用替代方案。
代码示例 #
easysearch.yml 基础配置 #
indices:
id_field_data:
enabled: true
禁用配置 #
indices:
id_field_data:
enabled: false
动态更新配置 #
PUT /_cluster/settings
{
"transient": {
"indices.id_field_data.enabled": false
}
}
推荐的替代实现 #
PUT /my_index
{
"mappings": {
"properties": {
"id_field": {
"type": "keyword",
"doc_values": true
}
}
}
}
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 的排序/聚合
- 使用其他字段
注意事项 #
已弃用: 此功能已被标记为弃用,不应在新代码中使用。
默认启用: 默认值为
true,保持向后兼容。替代方案: 官方推荐使用 doc_values 替代。
动态更新: 支持动态更新,修改后立即生效。
内存考虑: 禁用可以减少内存使用。
性能影响: doc_values 性能比 fielddata 更好。
规划迁移: 建议规划迁移到替代方案。
索引映射: 替代字段需要添加到索引映射中。
数据更新: 需要更新现有文档以包含替代字段。
测试验证: 迁移后需要测试所有相关功能。





