美文网首页
elasticsearch中默认的mapping

elasticsearch中默认的mapping

作者: 温岭夹糕 | 来源:发表于2021-03-03 01:22 被阅读0次

前言

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介绍中有这么一行描述

image.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

相关文章

网友评论

      本文标题:elasticsearch中默认的mapping

      本文链接:https://www.haomeiwen.com/subject/nldyrktx.html