Elasticsearch-79-fielddata filter的细粒度内存加载控制以及预加载机制

filter的细粒度内存加载控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /test_index/_mapping/my_type
{
"properties": {
"my_field": {
"type": "text",
"fielddata": {
"filter": {
"frequency": {
"min": 0.01,
"min_segment_size": 500
}
}
}
}
}
}

主要设置的就是两个值,一个是min,一个是min_segment_size

min: 仅仅加载至少1%的doc中出现过的term对应的fielddata
比如说,有一个词 hello, 总共有1000个doc,hello必须在10个doc中出现,那么这个hello对应的fielddata才会加载到内存中来

min_segment_size: 少于500个doc的segment不加载fielddata
加载fielddata的时候,也是按照segment去进行加载的,某个segment里面的doc数量少于500个的话,这个segment的fielddata就不会加载

这个一般不用去设置,了解一下就好了

fielddata预加载机制

如果真的要对分词的field执行聚合,那么每次都在query-time现场生成fielddata并加载到内存中来,这样的话速度是比较慢的, 我们可以预先生成加载fielddata到内存中来

fielddata预加载
1
2
3
4
5
6
7
8
9
10
11
POST /test_index/_mapping/test_type
{
"properties": {
"test_field": {
"type": "string",
"fielddata": {
"loading" : "eager"
}
}
}
}

这样可以将fielddata的生成变为index-time,建立倒排索引的时候,就同步生成fielddata并且加载到内存中,这样的话对分词field的聚合性能会大幅度增强

序号标记预加载

global ordinal 原理:

假设有如下几个doc,分别是

1
2
3
4
doc1: status1
doc2: status2
doc3: status2
doc4: status1

在这样有很多重复值的情况,会进行global ordinal标记

status1 –> 0
status2 –> 1

标记完成后,如下

1
2
3
4
doc1: 0
doc2: 1
doc3: 1
doc4: 0

建立fielddata也会是这个样子的,这样的好处就是减少重复字符串的出现次数,减少内存的消耗

设置的语法如下:

1
2
3
4
5
6
7
8
9
10
11
POST /test_index/_mapping/test_type
{
"properties": {
"test_field": {
"type": "string",
"fielddata": {
"loading" : "eager_global_ordinals"
}
}
}
}