Fielddata 是 Elasticsearch 中的一个术语,指的是一些字段上值的聚合操作。ES 默认情况下,对于每个字段,都会存储原始的值和倒排索引来支持搜索。然而,在某些场景下,我们也需要聚合数据,计算最小、最大、平均值等指标,这就用到了 fielddata。下面将从几个方面对 fielddata 进行详细解读。
一、基础概念
Fielddata 中有两种类型的值:doc value 和 fielddata cache。其中,doc value 本质是一种优化索引的方式,可以加速排序和聚合操作。doc value 值是预先计算好的存储在内存中的值。相比之下,fielddata cache 存储在磁盘上的原始值,需要在聚合操作时再进行计算。fielddata cache 默认情况下是禁用的,需要手动启用。
二、聚合操作
聚合操作是 Elasticsearch 中 fielddata 的一个核心使用场景。最简单的聚合操作是计算最大值、最小值、平均值和唯一值,可以通过以下语句进行实现:
GET /my_index/_search
{
"aggs": {
"max_amount": { "max": { "field": "amount" } },
"min_amount": { "min": { "field": "amount" } },
"avg_amount": { "avg": { "field": "amount" } },
"unique_tags": { "cardinality": { "field": "tags" } }
}
}
另外,我们还可以使用 fielddata 对文本进行聚合操作。例如,以下语句计算商品品牌的销售总量:
GET /my_index/_search
{
"aggs": {
"brand_sales": {
"terms": {
"field": "brand.keyword"
},
"aggs": {
"total_sales": {
"sum": {
"field": "sales"
}
}
}
}
}
}
三、性能优化
Fielddata 相对于一些常用的 Elasticsearch 操作(如搜索)是非常消耗资源的。因此需要一定的性能优化。常见的优化方式包括:
1、启用 doc value
启用 doc value 可以提升排序、聚合操作的性能,占用更少的内存。
PUT my_index/_mapping/my_type
{
"properties": {
"my_field": {
"type": "long",
"doc_values": true
}
}
}
2、避免全量操作
避免全量操作可以大大减少聚合操作的耗时。因此,需要明确设置聚合、搜索、查询、过滤和排序等操作的范围和目标,尽量不对全部数据执行操作。
3、增加缓存大小
fielddata 的 cache 默认是 30% JVM 堆空间。如果数据量较大,缓存可能会非常满,导致性能问题。可以通过增加缓存大小解决这个问题。
PUT /my_index/_settings
{
"index": {
"fielddata": {
"cache": {
"size": "40%"
}
}
}
}
4、合理使用 filter
filter 比 query 更快,因为它可以减少 fielddata 的工作。过滤多个聚合操作时,尽量使用 filter 而不是 query。
四、总结
本文介绍了 Elasticsearch 中的 fielddata,讨论了其基础概念、聚合操作和性能优化。对于线上环境中的 fielddata 操作,需要根据具体的业务场景和数据量进行合理的性能优化,才能获得更好的使用效果。