02-aggregation-and-analysis-es控制聚合内存使用-elasticsearc
在采用es的bucket agg的时候,我们会经常操作string类型的字段,一个string字段设置为analyzed和not_analyzed对聚合有什么样的影响呢? 结论是影响非常大。下面是一个例子,先bulk进一批数据 POST /agg_analysis/data/_bulk { "index": {}} { "state" : "New York" } { "index": {}} { "state" : "New Jersey" } { "index": {}} { "state" : "New Mexico" } { "index": {}} { "state" : "New York" } { "index": {}} { "state" : "New York" } 然后通过term聚合去获取结果 GET /agg_analysis/data/_search?search_type=count { "aggs" : { "states" : { "terms" : { "field" : "state" } } } } 结果是: { ... "aggregations": { "states": { "buckets": [ { "key": "new", "doc_count": 5 }, { "key": "york", "doc_count": 3 }, { "key": "jersey", "doc_count": 1 }, { "key": "mexico", "doc_count": 1 } ] } } }
这可不是我们想要的,聚合竟然是根据每个单词聚合的,为啥会这样?原因很简单:聚合的数据是从倒排索引中建立的,而倒排索引的数据是analyzed的。 我们需要做的是重新设置mapping DELETE /agg_analysis/ PUT /agg_analysis { "mappings": { "data": { "properties": { "state" : { "type": "string", "fields": { "raw" : { "type": "string", "index": "not_analyzed" } } } } } } }
POST /agg_analysis/data/_bulk { "index": {}} { "state" : "New York" } { "index": {}} { "state" : "New Jersey" } { "index": {}} { "state" : "New Mexico" } { "index": {}} { "state" : "New York" } { "index": {}} { "state" : "New York" }
GET /agg_analysis/data/_search?search_type=count { "aggs" : { "states" : { "terms" : { "field" : "state.raw" } } } }
This time we explicitly map the state field and include a not_analyzed sub-field.
The aggregation is run on state.raw instead of state.
Now when we run our aggregation,we get results that make sense:
{ ... "aggregations": { "states": { "buckets": [ { "key": "New York", { "key": "New Jersey", { "key": "New Mexico", "doc_count": 1 } ] } } }
在日常开发中这种问题总会出现,你要记住这个issue,通常,很少会有业务使用分析字段做聚合的,如果真的出现,你的做法就是加个字段然后同样的值然后分别使用即可。
high-cardinality memory implications 极其重要的内存潜在问题
这里还有个重要的理由避免聚合analyzed字段,因为把这些字段加入fielddata之后会占用大量的内存,这分析过程会生成大量的token,每个token都是独立的,大量的数据会占用大量的内存。 例如new york被analyzed会有 ne ew w y yo or rk
你可以想象这是多么可怕,特别是在分析段落字段的时候(例如商品描述),很容易造成内存溢出。 所以,在通过这些字段聚合之前,核对这个字段是否是analyzed的,不管是不是analzyzed的,越长的string字段绝对内存占用越大,所以得注意一下。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |