前言
es的核心概念主要是
- index(索引)
- doc(文档)
- clusters(集群)
- node(节点)
- 实例
其中文档是es中可搜索的最小单位,一个文档由一个或多个字段组成,类似mysql中表的一行数据记录,es每个文档都有唯一的id,可以由我们自己指定,也可以由es自动生成
普通的es文档(指被es搜索出的结果)
{
"_index" : "test_logs2",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : { //文档主要数据
"uid" : 1,
"username" : "test"
}
而索引index在es中有多种含义与作用
- 作为动词,es中创建文档的方式
put my_index/_doc/1
{
"uid":1,
"username":"test"
}
- 名词,es中将文档组织的方式,可以把索引类比为关系型数据库的一张表
- 动词,指被搜索
抛出问题1 : 当我们通过index操作(上面有举例)或create操作增加文档时,文档字段的默认类型是什么?
index操作是先删除后增加,版本号+1,create是_id不存在时才创建
先创建一个文档
POST操作多用于重复更新即多次执行结果增加,PUT多用于幂次操作即执行多次结果不变(虽然es中很多地方post和put都能用,但咱尽量遵循这个规则)
POST my_index/_doc/1 //重复两次分别观察get结果
{
"age":15
}
GET my_index/_doc/1 //version版本+1
PUT my_index/_create/1 //报错,提示文档已经存在
{...}
PUT my_index/_create/2
{
"name":"zjb",
"age":14,
"day1":"2020/8/1",
"day2":"2020-08-01",
"info":{
"firstname":"tom",
"lastname":"jon"
}
}
get /my_index/_mapping
捕获一下结果,注意我的标记位置
{
"my_index" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long" //数字自动识别为long类型
},
"day1" : {
"type" : "text", //字符识别为text类型
"fields" : {
"keyword" : { //增加子字段keyword(字段名)类型为keyword
"type" : "keyword",
"ignore_above" : 256
}
}
},
"day2" : {
"type" : "date" //识别为日期类型
},
"info" : { // info信息识别为object类型
"properties" : {
"firstname" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"lastname" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
像这种当索引不存在的同时写入文档自动创建索引的机制,官方称为 Dynamic Mapping,即es会根据文档信息推算出字段类型
Dynamic Mapping详细介绍
其中有在mapping field介绍中有这么一行描述
![](https://img.haomeiwen.com/i20602965/93c98482a89b8ce2.png)
即会根据字符串的不同格式,创建不同的类型,同时也会为字符串创建子字段
put my_test/_create/1
{
"age":"14",
"age_test":14,
"float":"12.1",
"float_test":12.1
}
结果集
{
"my_test" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "text", //emmm,好吧并没被识别成整形,这也挺好的
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"age_test" : {
"type" : "long"
},
"float" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"float_test" : {
"type" : "float"
}
}
}
}
}
既然能传入对象类型,那数组呢?
delete my_test
put my_test/_create/1
{
"name":["tom","jon"]
}
put my_test1/_create/1
{
"name":[2,3]
}
put my_test2/_create/1
{
"name":[2,"jon"]
}
put my_test3/_create/1
{
"name":["jon","2020-8-1"]
}
put my_test4/_create/1
{
"name":["2020-08-01","join"]
}
get /my_test/_mapping
get /my_test1/_mapping
get /my_test2/_mapping
get /my_test3/_mapping
get /my_test4/_mapping
其中my_test被识别为text
my_test1被识别为long
my_test2和4因为类型不同的原因报错
my_test3被识别为 text类型
那么可以得出结果:数组类型需要一致,会根据首个单元的类型去比较后面单元,如my_test4报错mapper [name] of different type, current_type [date], merged_type [text]
抛出问题2 : 能否修改mapping类型?
对于已有字段,一旦有数据写入就不能再修改,需要重建索引(联想到mysql innodb数据库,因为索引树存在的关系即使删除数据,表大小也不会改变,es是基于倒排索引创建索引的,重建索引本质上是重新实现倒排索引)
对于新增字段,取决于Dynamic的设置
"true" "false" "strict"
文档可索引 √ √ ×
字段可索引 √ × ×
Mapping被更新 √ × ×
即默认为true
当为false时,新增字段的数据能被写入也能被搜索但是新增的字段消失了
delete my_test
put my_test/_create/1
{
"name":["tom","jon"]
}
put my_test/_mapping
{
"dynamic":"false"
}
post my_test/_create/2
{
"age":12
}
get my_test/_doc/2 //只有 age:12字段
get /my_test/_mapping //只有一个字段name
post my_test/_search //查询不到
{
"query":{
"match": {
"age": "12"
}
}
}
当为strict时,新增写入直接报错
put my_test/_mapping
{
"dynamic":"strict"
}
put my_test/_create/3 //报错,不被允许写入
{
"age":12
}
put my_test/_create/3 //成功写入
{
"name":"Tina"
}
抛出问题3: 日期格式到底可以按我们的要求进行检测?
我们可以对日期的格式在mapping中进行规范设置
当我们不想检测日期格式时可以设置 date_detection为“false”
put my_test/_create/1
{
"age":12
}
post my_test/_mapping
{
"date_detection":"false"
}
put my_test/_create/2
{
"age":12,
"data":"2020-08-01"
}
get my_test/_mapping
设置我们指定的格式dynamic_date_formats
post my_test/_mapping
{
//通过之前的实验我们知道yyyy/MM/dd会被默认的dynamic识别为text
"dynamic_date_formats":["MM/dd/yyyy","yyyy/MM/dd"]
}
post my_test/_create/2
{
"age":12,
"dates":"08/01/2020",
"create":"2020/08/01"
}
get my_test/_mapping
结果为
{
"my_test" : {
"mappings" : {
"dynamic_date_formats" : [
"MM/dd/yyyy",
"yyyy/MM/dd"
],
"properties" : {
"age" : {
"type" : "long"
},
"create" : {
"type" : "date",
"format" : "yyyy/MM/dd"
},
"dates" : {
"type" : "date",
"format" : "MM/dd/yyyy"
}
}
}
}
}
利用Dynamic Template对默认字段类型进行进一步控制
利用正则进行自定义优先级控制
put my_index
{
"mappings":{
"dynamic_templates":[
{
"dates":{
"match":"log_*", //匹配log_前缀的字段名
"unmatch":"*_text", //不匹配_text后缀的字段名
"mapping":{
"type":"keyword"
}
}
}
]
}
}
post my_index/_doc/1
{
"log_name":"binlog-1", //被识别为keyword
"log_text":"binlog-2" //被识别为text
}
get my_index/_mapping
网友评论