映射:fielddata 詳解
- 1.fielddata 是什么
- 2.fielddata 的工作原理
- 3.主要用法
- 3.1 啟用 fielddata(通常在 text 字段上)
- 3.2 監控 fielddata 使用情況
- 3.3 清除 fielddata 緩存
- 4.使用場景示例
- 示例 1:對 text 字段進行聚合
- 示例 2:對 text 字段進行排序
- 5.fielddata 與 doc_values 的區別
- 6.注意事項
- 7.最佳實踐
1.fielddata 是什么
fielddata
是 Elasticsearch 中一種數據結構,用于在內存中緩存字段數據,主要服務于以下場景:
- 聚合操作(Aggregations)
- 排序(Sorting)
- 腳本計算(Scripting)
- 某些類型的查詢(如
field
字段上的term
查詢)
當需要對 text
字段或其他非 doc_values
支持的字段執行上述操作時,Elasticsearch 需要將這些字段的值加載到內存中,這就是 fielddata
的作用。
2.fielddata 的工作原理
- 按需加載:當第一次需要對某個字段執行聚合 / 排序等操作時,Elasticsearch 會從磁盤讀取該字段的所有值并構建內存中的數據結構。
- 存儲在 JVM 堆內存:
fielddata
會占用 JVM 堆內存空間。 - 字段級啟用:默認情況下,
text
字段禁用fielddata
,keyword
字段使用doc_values
而非fielddata
。
3.主要用法
3.1 啟用 fielddata(通常在 text 字段上)
PUT my_index/_mapping
{"properties": {"my_text_field": { "type": "text","fielddata": true}}
}
3.2 監控 fielddata 使用情況
GET _nodes/stats/indices/fielddata?fields=*
3.3 清除 fielddata 緩存
POST my_index/_cache/clear?fielddata=true
4.使用場景示例
示例 1:對 text 字段進行聚合
GET my_index/_search
{"size": 0,"aggs": {"my_terms": {"terms": {"field": "my_text_field" // 需要該字段啟用 fielddata}}}
}
示例 2:對 text 字段進行排序
GET my_index/_search
{"sort": [{"my_text_field": {"order": "asc"}}]
}
5.fielddata 與 doc_values 的區別
特性 | fielddata | doc_values |
---|---|---|
構建時機 | 查詢時按需構建 | 索引時預先構建 |
存儲位置 | JVM 堆內存 | 磁盤(操作系統緩存) |
內存占用 | 高 | 低 |
適用字段類型 | 主要為 text 字段 | 主要為 keyword / numeric / date 等字段 |
默認啟用 | text 字段默認禁用 | 支持的字段默認啟用 |
6.注意事項
- 內存消耗:
fielddata
會顯著增加內存使用,特別是高基數(大量唯一值)字段。 - 性能影響:首次加載
fielddata
可能導致查詢延遲。 - 替代方案:對于
keyword
/numeric
/date
等字段,優先使用doc_values
。 - 熔斷機制:Elasticsearch 有
fielddata
熔斷器防止內存耗盡。
7.最佳實踐
-
盡量避免在
text
字段上啟用fielddata
。 -
如需對文本進行聚合/排序,考慮使用多字段(
multi-field
)映射:"my_field": {"type": "text","fields": {"keyword": {"type": "keyword"}} }
然后對
my_field.keyword
進行操作。 -
監控
fielddata
內存使用,設置合理的熔斷閾值。