如何在Elasticsearch中白名单对象键并动态确定字段类型?
解决Elasticsearch HTTP请求日志的字段爆炸问题
一、请求头白名单自动映射(text+keyword类型)
你之前的动态模板配置不生效,核心问题是把headers的dynamic设为false,导致Elasticsearch不会处理该对象下的动态字段,同时根级的动态模板无法精准匹配req.headers下的字段。以下是正确的配置:
PUT /test-index/_mapping { "dynamic": false, "properties": { "req": { "dynamic": true, "properties": { "headers": { "dynamic": true, "dynamic_templates": [ { "whitelist_headers": { "match_pattern": "regex", "path_match": "req.headers.(accept|content-type|user-agent|sec-.*)", "match_mapping_type": "string", "mapping": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } ] } } } } }
关键说明:
headers的dynamic设为true,让Elasticsearch处理该对象下的动态字段,同时通过动态模板过滤白名单。path_match用正则匹配白名单字段:- 明确指定允许的字段(如
accept、content-type) - 支持通配符匹配前缀(如
sec-.*匹配所有以sec-开头的请求头)
- 明确指定允许的字段(如
match_mapping_type: "string"确保只对字符串类型的请求头应用该模板(请求头基本都是字符串)。
测试验证:
POST test-index/_doc { "req": { "foo": "bar", "headers": { "user-agent": "test", "sec-foo": "test", "do-not-index-me": "test", "accept": "application/json" } } } GET /test-index/_search { "query": { "term": { "req.headers.user-agent.keyword": "test" } } }
注意:term查询要使用
.keyword子字段,因为text类型的字段默认会被分词,直接用req.headers.user-agent需要用match查询。
二、查询字符串白名单+自动类型识别
对于查询字符串参数,需要白名单过滤且让Elasticsearch自动识别字段类型,配置思路类似,只需修改映射模板的type为{dynamic_type}:
PUT /test-index/_mapping { "dynamic": false, "properties": { "req": { "dynamic": true, "properties": { "headers": { // 保留上面的请求头配置 }, "query": { "dynamic": true, "dynamic_templates": [ { "whitelist_query_params": { "match_pattern": "regex", "path_match": "req.query.(id|name|page|size)", "mapping": { "type": "{dynamic_type}" } } } ] } } } } }
关键说明:
{dynamic_type}让Elasticsearch根据字段值自动识别类型(如数字、字符串、布尔值等)。path_match指定允许的查询参数白名单,不在列表中的参数不会被索引。
测试验证:
POST test-index/_doc { "req": { "query": { "id": 123, "name": "test", "page": 2, "ignore-me": "should not be indexed" } } } GET /test-index/_search { "query": { "term": { "req.query.id": 123 } } }
内容的提问来源于stack exchange,提问作者shampoopy
相关产品推荐
相关产品推荐

