ES中的映射(mapping)是用于定义索引中文档以及文档中的字段如何被存储和索引(动词)的一种机制,例如,通过映射我们可以进行如下的这些定义:
-
索引文档中,哪些字符型字段应该被当做全文本类型;
-
哪些字段是数值型、时间日期型或者地理空间数据;
-
定义时间日期型字段的格式;
-
为动态添加的字段自定义映射规则;
1 映射与字段¶
一个映射中的字段可以分为两种类型:
-
元数据字段。元数据字段用于自定义如何处理文档的相关元数据,例如
_index
,_id
,_source
等字段。更多元数据字段,可以参看官方文档 -
常规字段。也就是我们文档中我们的目标数据,例如users索引中的usename字段,这类字段都拥有自己的数据类型。
另外,与关系型数据库一样,ES中每一个字段都有对应的数据类型,这些也是在映射中进行配置的。数据类型定义了数据的存储和索引方式,例如keyword类型和text类型虽然都是字符串类型,但是text可进行全文索引,但是不能进行排序和过滤,keyword类型刚好相反。一些常见数据类型如下:
2 创建映射¶
动态映射
ES中存在动态映射机制,映射在使用之前不需要显示地定义,通过动态映射,向索引中添加未出现过的字段时,ES会字段判断数据类型,并创建映射。新字段既可以添加到顶层映射类型,也可以添加到内部对象或者嵌套字段。
如果需要,我们也自定义动态映射规则并配置其自动用于新字段的映射。
显式映射
与动态映射相对应的是显式映射,显示映射是指手动创建映射,这一过程可以在创建索引时完成,也可以在向已存在的索引中添加字段时创建。
创建一个users索引,包含age、email、name三个字段:
3 更新映射¶
通过PUT /<index>/_mappint
这一API,可以完成添加字段映射,也就是对映射进行修改等一系列操作。例如,向刚创建的users索引中添加一个user_id字段,字段类型为keyword:
3.1 添加一个字段映射¶
可以同时向多个索引中添加映射:
3.2 向嵌套字段中添加新的字段¶
注意,只有嵌套字段才能进行这一操作,我们先创建一个包含嵌套字段的索引,假设嵌套字段为name
,name
中包含firstname
:
现在,name
字段中只有一个firstname
的嵌套值,现在继续往name
中添加一个secondname
:
3.3 同一字段添加多个映射¶
为同一字段添加多个映射后,我们可以使用多种方式对该字段进行索引。为方便接下来演示,我们先创建一个blogs索引,其字段映射如下:
在bolgs索引中,title字段被设置为文本类型,可用于全文本搜索,但是却不能使用关键字类型的排序等聚合分析,为解决这一问题,我们可以再次基础上,为title字段添加一个keyword类型的映射。
3.4 修改某字段映射配置参数¶
创建一个test1索引,映射信息如下:
其中,user_id有配置参数ignore_above,值为20,现在,我们需要将其值设置为100,可以这么做:
除了ignore_above参数外,映射中还有很多参数可以修改和配置,可以参看官方文档
3.5 修改字段映射类型¶
事实上,除了上述修改映射字段的参数外,我们并不能修改字段的其他信息进行修改,例如不能修改映射类型,因为这将导致已存在文档的索引失效。如果非做不可,那么,我们可以先创建一个索引,然后将数据迁移过去。例如在上文中创建的索引test1,我们需要将user_id字段的映射类型修改为long,那么我们需要先创建一个索引,假设名为test1_new。
然后把数据从test1迁移到test1_new中:
3.6 重命名一个字段¶
与修改一个字段映射一样,重命名一个字段也是不被运行的,这一操作将导致索引中已存在数据索引失效。不过,我们可以使用ES中别名机制来解决这一问题。我们先创建一个users索引:
现在,我们需要将username字段重命名为name,那么,我们可以为username字段创建一个别名,使用上是等效的。
4 查看映射¶
4.1 查看指定索引的映射¶
4.2 查看多个映射信息¶
可以采用GET /index1,index2/_mapping
的方式同时查看多个索引的映射信息:
如果有查看所有映射的信息,有以下三种方式:
GET /*/_mapping
GET /_all/_mapping
GET /_mapping
4.3 查看指定字段的映射信息¶
查看指定索引下某一字段的映射:
也可以指定查看嵌套字段的映射:
使用通配符查看多个映射:
ES中还提供查看指定多个索引下字段映射的API:
GET /<index1>,<index2>/_mapping/field/<field>
查看所有所有下某个字段映射:
GET /_all/_mapping/field/<field>
GET /_all/_mapping/field/*.<field>