ELK 6迁移至ELK 8后source.geo.country_iso_code聚合过滤失效问题
ELK 8中source.geo.country_iso_code过滤无匹配的解决方法
问题根源
ELK 8里的source.geo.country_iso_code字段默认大概率是text类型,而term查询是精确匹配倒排索引里的原始词项。text类型字段会被分词器处理(比如自动转小写),导致你用"AU"做精确匹配时,和索引中存储的实际值不匹配。而ELK 6中的geoip.country_code2通常是keyword类型,天然支持精确匹配,所以之前的查询能正常工作。
验证字段类型
先确认字段的映射情况,执行以下命令查看索引中该字段的类型:
GET /你的索引名称/_mapping/field/source.geo.country_iso_code
如果返回结果里包含keyword子字段,说明可以通过该子字段实现精确匹配。
修改后的查询DSL
把聚合过滤里的字段改为source.geo.country_iso_code.keyword,就能正常匹配AU的记录了:
{ "query": { "bool": { "filter":[ {"range":{"@timestamp":{"gte":"<lower>","lt":"<upper>"}}} ], "must": [ {"match": {"http.response.status_code":"200"}}, {"match": {"vhost":"<vhost>"}} ] } }, "_source": ["url.original","vhost","@timestamp","http.response.body.bytes","source.address","source.geo.country_iso_code"], "size": 0, "aggs": { "AU": { "filter": { "term": { "source.geo.country_iso_code.keyword": "AU"} }, "aggs": { "sum_bytes": { "sum": {"field": "http.response.body.bytes"}}, "ip_count": { "cardinality": { "field": "source.address" }} } }, "int": { "filter": { "bool": { "must_not": { "term": { "source.geo.country_iso_code.keyword": "AU" }}} }, "aggs": { "sum_bytes": { "sum": {"field": "http.response.body.bytes"}}, "ip_count": { "cardinality": { "field": "source.address" }} } } } }
长期优化方案
如果这个字段只用来做精确匹配过滤,建议直接修改索引映射,把source.geo.country_iso_code设为keyword类型,这样后续查询不用再加.keyword后缀:
PUT /你的索引名称/_mapping { "properties": { "source": { "properties": { "geo": { "properties": { "country_iso_code": { "type": "keyword" } } } } } } }
注意:修改已有索引的映射后,需要重新索引数据才能让新的映射生效。
内容的提问来源于stack exchange,提问作者Robert Cohen
相关产品推荐
相关产品推荐

