Fielddata 是 Elasticsearch 中的一個(gè)術(shù)語(yǔ),指的是一些字段上值的聚合操作。ES 默認(rèn)情況下,對(duì)于每個(gè)字段,都會(huì)存儲(chǔ)原始的值和倒排索引來支持搜索。然而,在某些場(chǎng)景下,我們也需要聚合數(shù)據(jù),計(jì)算最小、最大、平均值等指標(biāo),這就用到了 fielddata。下面將從幾個(gè)方面對(duì) fielddata 進(jìn)行詳細(xì)解讀。
一、基礎(chǔ)概念
Fielddata 中有兩種類型的值:doc value 和 fielddata cache。其中,doc value 本質(zhì)是一種優(yōu)化索引的方式,可以加速排序和聚合操作。doc value 值是預(yù)先計(jì)算好的存儲(chǔ)在內(nèi)存中的值。相比之下,fielddata cache 存儲(chǔ)在磁盤上的原始值,需要在聚合操作時(shí)再進(jìn)行計(jì)算。fielddata cache 默認(rèn)情況下是禁用的,需要手動(dòng)啟用。
二、聚合操作
聚合操作是 Elasticsearch 中 fielddata 的一個(gè)核心使用場(chǎng)景。最簡(jiǎn)單的聚合操作是計(jì)算最大值、最小值、平均值和唯一值,可以通過以下語(yǔ)句進(jìn)行實(shí)現(xiàn):
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 對(duì)文本進(jìn)行聚合操作。例如,以下語(yǔ)句計(jì)算商品品牌的銷售總量:
GET /my_index/_search
{
"aggs": {
"brand_sales": {
"terms": {
"field": "brand.keyword"
},
"aggs": {
"total_sales": {
"sum": {
"field": "sales"
}
}
}
}
}
}
三、性能優(yōu)化
Fielddata 相對(duì)于一些常用的 Elasticsearch 操作(如搜索)是非常消耗資源的。因此需要一定的性能優(yōu)化。常見的優(yōu)化方式包括:
1、啟用 doc value
啟用 doc value 可以提升排序、聚合操作的性能,占用更少的內(nèi)存。
PUT my_index/_mapping/my_type
{
"properties": {
"my_field": {
"type": "long",
"doc_values": true
}
}
}
2、避免全量操作
避免全量操作可以大大減少聚合操作的耗時(shí)。因此,需要明確設(shè)置聚合、搜索、查詢、過濾和排序等操作的范圍和目標(biāo),盡量不對(duì)全部數(shù)據(jù)執(zhí)行操作。
3、增加緩存大小
fielddata 的 cache 默認(rèn)是 30% JVM 堆空間。如果數(shù)據(jù)量較大,緩存可能會(huì)非常滿,導(dǎo)致性能問題。可以通過增加緩存大小解決這個(gè)問題。
PUT /my_index/_settings
{
"index": {
"fielddata": {
"cache": {
"size": "40%"
}
}
}
}
4、合理使用 filter
filter 比 query 更快,因?yàn)樗梢詼p少 fielddata 的工作。過濾多個(gè)聚合操作時(shí),盡量使用 filter 而不是 query。
四、總結(jié)
本文介紹了 Elasticsearch 中的 fielddata,討論了其基礎(chǔ)概念、聚合操作和性能優(yōu)化。對(duì)于線上環(huán)境中的 fielddata 操作,需要根據(jù)具體的業(yè)務(wù)場(chǎng)景和數(shù)據(jù)量進(jìn)行合理的性能優(yōu)化,才能獲得更好的使用效果。