"mappings": {
"_default_": { "dynamic_templates": [ { "string_fields": { "mapping": { "index": "analyzed", "omit_norms": true, "type": "string", "fields": { "raw": { "index": "not_analyzed", "ignore_above": 256, "type": "string" } } }, "match": "*", "match_mapping_type": "string" } } ], "_all": { "enabled": true }, "properties": { "@version": { "type": "string", "index": "not_analyzed" }, "geoip": { "dynamic": "true", "properties": { "location": { "type": "geo_point" } } } } },
"hkt_log": { "dynamic_templates": [ { "string_fields": { "mapping": { "index": "analyzed", "omit_norms": true, "type": "string", "fields": { "raw": { "index": "not_analyzed", "ignore_above": 256, "type": "string" } } }, "match": "*", "match_mapping_type": "string" } } ], "_all": { "enabled": true }, "properties": { "@timestamp": { "type": "date", "format": "dateOptionalTime" }, "@version": { "type": "string", "index": "not_analyzed" }, "geoip": { "dynamic": "true", "properties": { "location": { "type": "geo_point" } } }, "host": { "type": "string", "norms": { "enabled": false }, "fields": { "raw": { "type": "string", "index": "not_analyzed", "ignore_above": 256 } } }, "message": { "type": "string", "norms": { "enabled": false }, "fields": { "raw": { "type": "string", "index": "not_analyzed", "ignore_above": 256 } } }, "path": { "type": "string", "norms": { "enabled": false }, "fields": { "raw": { "type": "string", "index": "not_analyzed", "ignore_above": 256 } } }, "type": { "type": "string", "norms": { "enabled": false }, "fields": { "raw": { "type": "string", "index": "not_analyzed", "ignore_above": 256 } } } } } }
当logstash的输出插件为elasticsearch时,logstash在向ES中index数据,会自动为当前创建一个“default“的映射,后面所有该索引下新建的type mapping都将继承这个default的映射。
这个default映射,_all字段默认是disabled,这里将其enabled
默认增加@version字段
geoip字段dynamic true表示该字段下可以动态的添加新字段
下面的type hkt_log继承了default的映射内容。
通过dynamic_templates,你可以拥有对新字段的动态映射规则拥有完全的控制。你设置可以根据字段名称或者类型来使用一个不同的映射规则。
每个模板都有一个名字,可以用来描述这个模板做了什么。同时它有一个mapping用来指定具体的映射信息,和至少一个参数(比如match)用来规定对于什么字段需要使用该模板。
模板的匹配是有顺序的 - 第一个匹配的模板会被使用。
上面logstash的模板中定义一个所有字符串字段的统计设置模板:
{
"string_fields": { "mapping": { "index": "analyzed", "omit_norms": true, "type": "string", "fields": { "raw": { "index": "not_analyzed", "ignore_above": 256, "type": "string" } } }, "match": "*", "match_mapping_type": "string" } }
另外还有path_match参数用于匹配对象中字段的完整路径,比如address.*.name可以匹配如下字段:
{
"address":
"city":
"name": "New York"
}
}
}
unmatch和path_unmatch模式能够用来排除某些字段,没有被排除的字段则会被匹配。
fields 是一个多字段属性,假如有一个字段叫message,那么表示会有一个子段message.raw,其中保存着message字段的原始内容,不会被分析器分析。
我们可以看到hkt_log类型的映射完全继承了default的映射内容,同时动态的添加了特定字段,但是可以看到所有字符串字段都遵循着string_fields模板的定义,如message字段:
"message": {
"type": "string",
"norms": {
"enabled": false
},
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed",
"ignore_above": 256
}
}
}
message会有一个子段raw,保存着未经分析器分析过的原始内容。
那了多了这样一个字段有什么好处呢?
我们先向hkt_log中增加一个文档:
put logstash-2015.10.01/hkt_log/1
{
"message": "jfy/zhyy?123",
"@version": "1",
"@timestamp": "2015-11-12T03:14:41.435Z",
"type": "hostapd1_log",
"host": "server114",
"path": "/root/hostapd/hostapd1.log"
}
下面查询message字段中包含”?”的文档:
{
"query":{ "regexp":{ "message":{"value":".*\\?.*"} } } }
查不到结果,改成:
{
"query":{ "regexp":{ "message.raw":{"value":".*\\?.*"} } } }
可以查询到。
这是因为message字段内容”jfy/zhyy?123”被分析器分析后,变成了三个单词:jfy,zhyy,123,其中的”/”和”?”分析器是忽略掉的。
POST logstash-2015.10.01/_analyze
jfy/zhyy?123
{
"tokens": [
{
"token": "jfy",
"start_offset": 0,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "zhyy",
"start_offset": 4,
"end_offset": 8,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "123",
"start_offset": 9,
"end_offset": 12,
"type": "<NUM>",
"position": 3
}
]
}
而message.raw是原样存储,因此用通配符就能查询。