在上一篇文章中,我们介绍了elasticsearch的结果过滤,高亮查询,聚合函数,分组查询等操作,《大数据搜索与可视化分析(3)elasticsearch查询进阶-2》,本文我们将学习elasticsearch的mappings相关知识点。
在关系型数据库中,比如mysql中,创建数据库后,必须先定义表结构,如下面图片中所展示的mysql表结构
向该表插入的数据必须要符合该表中各个字段所定义好的结构,否则插入数据将报错。
前面几篇文章中,我们向elasticsearch中插入数据,都是直接插入,无需定义任何表结构,这是因为,在插入数据时,elasticsearch会根据字段的值判断该值所属的类型,如name为文本型,age为long型等等。
如下面的例子
1、向elasticsearch中插入一条数据
PUT test2/_doc/1{ "name":"王百万"}
2、查询当前索引信息
由返回结果可以看到,分为两大部分,第一部分关于test2索引类型相关的,包括该索引是否有别名aliases,然后就是mappings信息,包括索引类型doc,各字段的详细映射关系都收集在properties中。
另一部分是关于索引test2的settings设置。包括该索引的创建时间,主副分片的信息,UUID等等。
3、向elasticsearch中插入数据,并重新查看test2索引信息
我们可以看到,settings没有变化,只是mappings中多了一条关于age的映射关系,这一切都是elasticsearch自动的。
那么,什么是mappings(映射)呢?
映射mappings就是elasticsearch中定义的表结构。elasticsearch中的映射用来定义一个文档及其包含的字段如何存储和索引的过程。例如,我们可以使用映射来定义:
哪些字符串应该被视为全文字段。
哪些字段包含数字、日期或者地理位置。
定义日期的格式。
自定义的规则,用来控制动态添加字段的的映射。
也就是说,mappings既可以通过elasticsearch自动生成,也可以手动定义。
当定义表结构的时候,需要我们来了解一下字段的数据类型:
简单类型,如文本(text)、关键字(keyword)、日期(date)、整形(long)、双精度(double)、布尔(boolean)或ip。
可以是支持JSON的层次结构性质的类型,如对象或嵌套。
或者一种特殊类型,如geo_point、geo_shape或completion。
接下来,我们手动定义一个mappings映射,看一看和elasticsearch自动生成的mappings有什么不同。
PUT mappings_test2{ "mappings": { "properties": { "name":{ "type": "text" }, "age":{ "type": "long" } } }}
我们在创建索引mappings_test2的过程中,为该索引定制化类型(设计表结构),使用了默认的映射类型_doc;指定字段或者属性都在properties内完成。
查看mappings_test2的索引信息
{ "mappings_test2" : { "aliases" : { }, "mappings" : { "properties" : { "age" : { "type" : "long" }, "name" : { "type" : "text" } } }, "settings" : { "index" : { "creation_date" : "1592719863269", "number_of_shards" : "1", "number_of_replicas" : "1", "uuid" : "BVoULWRnTeW-Cdw7RtSoEg", "version" : { "created" : "7070099" }, "provided_name" : "mappings_test2" } } }}
对比和elasticsearch自动创建的mappings,可以看出,两种mappings大体相同,自动创建的mappings中会附加keyword字段,而手动显示创建的mappings中则不会包含keyword字段。
接下来,我们向mappings_test2中添加数据
PUT mappings_test2/_doc/1{ "name":"张三", "age":19}
查询数据,和elasticsearch自动创建的mappings中数据的查询结果是相同的。
mappings细分又可以分为动态映射(dynamic mapping)和静态(显式)映射(explicit mapping)和精确(严格)映射(strict mappings),具体由dynamic属性控制。
elasticsearch默认为动态映射,即新添加的字段,由elasticsearch判断其类型并自动创建mappings。
修改elasticsearch的mappings可以通过dynamic字段进行修改
设置mappings为静态(显示)映射
PUT mappings_test3{ "mappings": { "dynamic":false, "properties": { "name":{ "type": "text" }, "age":{ "type": "long" } } }}
插入数据是没有问题的,无论新增多少字段,如当前例子为新增了一个desc字段
PUT mappings_test3/_doc/1{ "name":"张三", "age":11, "desc":"百家姓"}
但是如果查询时是通过新增字段进行查询的,则输出结果为空
我们再来查看一下mappings
可以看到elasticsearch并没有为新增的desc建立映射关系。所以查询不到。当elasticsearch察觉到有新增字段时,因为`dynamic:false`的关系,会忽略该字段,但是仍会存储该字段。
设置mappings为严格映射
PUT mappings_test4{ "mappings": { "dynamic":"strict", "properties": { "name":{ "type": "text" }, "age":{ "type": "long" } } }}
添加数据
错误提示,严格动态映射异常,当`dynamic:strict`的时候,elasticsearch如果遇到新字段,会抛出异常。
小结:
动态映射(dynamic:true):动态添加新的字段(或缺省)。
静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现在查询中
严格模式(dynamic:strict):如果遇到新的字段,就抛出异常。