本文共 9218 字,大约阅读时间需要 30 分钟。
mapping是类似于数据库中的表结构定义,主要作用如下:
GET /[index_name]/_mapping
其中 keyword表示部分次的字符串类型
mapping中的字段类型一旦设置,禁止直接修改,因为 lucene实现的倒排索引生成后不允许修改,应该重新建立新的索引,然后做reindex操作。
但是可以新增字段,通过 dynamic 参数来控制字段的新增,这个参数的值如下:
首先创建名为 my_index的索引并设置mapping:
PUT my_index{ "mappings": { "doc": { "dynamic": false, "properties": { "title": { "type": "text" }, "name": { "type": "keyword" }, "age": { "type": "integer" } } } }}
其中包含了 title、name、age三个字段
查询索引的mapping设置:
GET my_index/_mapping
然后写入一个文档:
PUT my_index/doc/1{ "title": "hello world", "desc": "this is book"}
注意,这里在mapping设置中,”dynamic”: false,表示在写入文档时,如果写入字段不存在也不会报错。这里的desc字段就是不存在的字段。
查询一下写入的文档:
GET my_index/doc/_search{ "query": { "match": { "title": "hello" } }}
可以通过 title字段查询到文档的内容
如果说想通过desc字段查询文档内容呢?当然是查不到的:
GET my_index/doc/_search{ "query": { "match": { "desc": "book" } }}
可以验证一下”dynamic”: strict模式:
首先删除索引:DELETE my_index
然后修改索引mapping设置:
PUT my_index{ "mappings": { "doc": { "dynamic": "strict", "properties": { "title": { "type": "text" }, "name": { "type": "keyword" }, "age": { "type": "integer" } } } }}
在重新创建文档:
PUT my_index/doc/1{ "title": "hello world", "desc": "this is book"}
在strict 模式下插入不存在的字段将会出现报错
作用是将该字段的值复制到目标字段,实现类似_all的作用。不会出现在_source中,只能用来搜索。
PUT my_index4{ "mappings": { "doc": { "properties": { "first_name": { "type": "text" , "copy_to": "full_name" }, "last_name": { "type": "text" , "copy_to": "full_name" }, "full_name" : { "type": "text" } } } }}
可以看到这个index中,full_name的内容就是从 first_name 和 last_name 中复制过来的。
然后创建一个新的文档,文档只需要写first_name 和 last_name即可:
PUT my_index4/doc/1{ "first_name": "john", "last_name": "smith"}
最后查询一下文档的内容:
GET my_index4/_search{ "query": { "match": { "full_name": { "query": "john smith", "operator": "and" } } }}
这个查询语句意思是:查询包含关键字john smith的文档,必须同时包含两个关键字才返回。
index参数作用是控制当前字段是否被索引,默认为true,false表示不记录,即不可被搜索。
PUT my_index5{ "mappings": { "doc": { "properties": { "cookie": { "type": "text", "index": false }, "content": { "type": "text", "index": true } } } }}
这个index有两个字段,其中cookie设定为不可被搜索
写入文档:
PUT my_index5/doc/1{ "cookie": "name=mike", "content": "hello world"}
尝试分别查询一下两个字段,看看区别:
GET my_index5/_search{ "query": { "match": { "cookie": "mike" } }}GET my_index5/_search{ "query": { "match": { "content": "hello" } }
当在es中存储了一些不想要被检索的字段如身份证、手机等,这是对于这些字段就可以使用index设置为false,这样有一定的安全性还可以节省空间
index_options的作用是用于控制倒排索引记录的内容,有如下四种配置:
text类型的默认配置为positions,其他默认为docs。记录的内容越多,占据的空间越大。
这个参数的作用是当字段遇到null值的时候的处理策略,默认为null,即空值,此时es会忽略该值。可以通过这个参数设置某个字段的默认值。
多字段特性(multi-fields),表示允许对同一字段采用不同的配置,比如分词。
常见例子是对人名实现拼音搜索,只需要在人名中新增一个字段pinyin即可。但是这种方式不是十分优雅,multi-fields可以在不改变整体结构的前提下,增加一个子字段:
在前面说过,在写入文档的时候如果index不存在的话es会自动创建这个索引。但是es是如何确定index字段的类型的呢?
首先es可以自动识别文档字段的类型,这样可以降低用户的使用成本。
es是依靠json文档的字段类型来实现自动识别字段类型的:
日期的自动识别可以自行配置日期的格式,默认情况下是:
["strict_date_opeional_time", "yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]
strict_date_opeional_time 是ISO 标准的日期格式,完整的格式如下:
YYYY-MM-DDhh:mm:ssTZD(eg:1997-07-16y19:20:30+01:00)
dynamic_date_formats:可以自定义日期类型
date_detection:可以关闭日期自动识别机制(默认开启)首先创建一个日期自动识别的索引:
PUT test_index{ "mappings": { "doc": { "dynamic_date_formats": ["MM/dd/yyyy"] } }}
然后创建一个文档:
PUT test_index/doc/1{ "create_time": "09/21/2016"}
查看:
GET test_index/_mapping
关闭日期自动识别可以如下:
字符串为数字的时候,默认不会自动识别为整型,因为字符串中出现数字是完全合理的。
numeric_detection 可以开启字符串中数字的自动识别。
Dynamic Templates 意为 动态模板,它的作用是允许根据es自动识别的数据类型、字段名等来动态设定字段类型。
可以实现的效果如下:
首先PUT一个文档,然后查看mapping:
PUT test_index/doc/1{ "name": "Tom"}GET test_index/_mapping
可以看到在默认情况下,字符串被识别成为text类型,并且有一个子字段keyword。
现在设置动态模板,要求匹配到string类型的字段设置为keyword:
PUT test_index{ "mappings": { "doc": { "dynamic_templates": [ { "strings_as_keywords": { "match_mapping_type": "string", "mapping": { "type": "keyword" } } } ] } }
重新创建文档并查看mapping:
name字段的类型变成了 keyword类型
现在想将以message开头的字段且为string的匹配称为text类型,其余为keyword:
PUT test_index{ "mappings": { "doc": { "dynamic_templates": [ { "message_as_text": { "match_mapping_type": "string", "match": "message", "mapping": { "type": "text" } } }, { "strings_as_keywords": { "match_mapping_type": "string", "mapping": { "type": "keyword" } } } ] } }}
Dynamic Templates 的匹配顺序是从上到下执行的,匹配到一个后后面的规则就会跳过
然后创建一个文档并查看mapping:
PUT test_index/doc/1{ "name": "john", "message": "good boy"}GET test_index/_mapping
可以看到message被设置为了text类型,name还是keyword
这样可以节省空间
自定义mapping 的步骤:
假设我得到了需要存入es的文档,首先将文档写入临时的index中:
PUT test_index/doc/1{ "referre": "-", "response_code": "200", "remote_ip": "172.0.0.1", "method": "POST", "username": "-", "http_version": "1.1", "body_sent": { "bytes": "0" }, "url": "/helloworld"}
然后查看es自动生成的mapping:
GET test_index/_mapping
现在希望将bytes设置为整型,url设置为text类型,其他都使用keyword(将上一步的输出复制过来就好):
PUT product_index{ "mappings": { "doc": { "properties": { "body_sent": { "properties": { "bytes": { "type": "long" } } }, "http_version": { "type": "keyword" }, "method": { "type": "keyword" }, "referre": { "type": "keyword" }, "remote_ip": { "type": "keyword" }, "response_code": { "type": "keyword" }, "url": { "type": "text" }, "username": { "type": "keyword" } } } } }
这样直接将测试index的mapping复制过来进行修改,不会遗漏字段,修改完成设置一个index的名称就行了。
然后就可以向实际的索引中写入文档了:
PUT product_index/doc/1{ "referre": "-", "response_code": "200", "remote_ip": "172.0.0.1", "method": "POST", "username": "-", "http_version": "1.1", "body_sent": { "bytes": "0" }, "url": "/helloworld"}
然后查看一下实际索引的mapping:
GET product_index/_mapping
上边的设置方法很直接,但是当字段比较多的时候显得复杂,可以使用动态模板进行匹配:
DELETE product_indexPUT product_index{ "mappings": { "doc": { "dynamic_templates": [ { "strings": { "match_mapping_type": "string", "mapping": { "type": "keyword" } } } ], "properties": { "body_sent": { "properties": { "bytes": { "type": "long" } } }, "url": { "type": "text" }, "username": { "type": "keyword" } } } } }
这里使用动态模板匹配所有字符串都设置为keyword类型,需要单独设置类型的在下面另行指出。
索引模板,index template,主要用于在新建索引时自动应用预先设置的配置,简化索引创建的步骤。
模板中可以设定索引的配置以及mapping,可以有多个模板,根据order设置,order大的覆盖小的范围。
模板加载顺序根据 order 从小到大加载,后面的大order的模板的配置将会覆盖小 order配置。
获取与删除的API 如下:
这里设置了两个索引模板:
PUT _template/test_template{ "index_patterns": ["te*", "bar*"], "order": 0, "settings": { "number_of_shards": 1 }, "mappings": { "doc": { "_source": { "enabled": false }, "properties": { "name": { "type": "keyword" } } } }}PUT _template/test_template2{ "index_patterns": ["test*"], "order": 1, "settings": { "number_of_shards": 1 }, "mappings": { "doc": { "_source": { "enabled": true } } }}
然后先创建一个foo_index,并获取一下它的mapping:
PUT foo_indexGET foo_index/_mapping
因为这个index没有被任何一个模板匹配到,所以它的mapping是空的
再创建一个bar_index,并获取一下它的mapping:
PUT bar_indexGET bar_index/_mapping
这个索引匹配到了test_template
再创建一个test_index,并获取一下它的index配置:
PUT test_indexGET test_index/
这个索引匹配到了test_template2模板,这使得索引的”_source”: {“enabled”: true}