版本控制

ES采用了乐观锁的方式来保证数据的一致性,也就是说,当用户对document进行操作的时候,并不需要对该document做加锁和解锁的操作,只需要指定要操作的版本即可。当版本号一致的时候,ES会允许该操作执行顺利,而当版本号存在冲突的时候,ES会提示冲突并且抛出异常。
ES的版本号的取值范围是1到2^63-1

  • 内部版本控制
    ES的内部版本号使用的是_version
内部版本号版本控制:只有当外部的版本号等于内部的版本号的时候,才允许用户做修改。
举例说明:

es 大于 条件 es大于1_ES


此时我在put的时候,手动给其一个版本号,如果版本号大于等于当前版本号则可以进行操作,否则无法执行


根据上图可以看到,我们put了一个数据之后,对id是1的数据进行修改,我们可以看到其_version的版本号+1,这个处理就是内部版本号的控制。


es 大于 条件 es大于1_ES_02


指明了版本号为1,但是我们实际版本号是3,所以不能操作。==只有两个版本号一致的时候才可以操作 ==

  • 外部版本控制
    ES在处理外部版本号的时候会与对内部版本号的处理有些不同。他不在是检查_version是否与请求中的数值相同,而是检查当前的_version是否比指定的数值小。如果请求成功,那么外部的版本号就会被存储到文档中的_version中。
    为了保持_version与外部版本控制的数据一致,使用version_type=external

外部版本控制的时候:是当外部的版本号大于当前的版本号的时候可以进行操作,并且将外部的版本号赋值给当前的版本号。

测试:

es 大于 条件 es大于1_版本号_03


可以根据上面的操作看出,PUT操作的时候,指明了外部的版本号。versinotallow=999&version_type=external,此时指明的版本号为999大于当前版本,所以允许用户操作,并将当前版本号改为外部的版本号999.

Mapping

什么是mapping

mapping就是映射,mapping定义了type中的每个字段的数据类型以及这些字段如何分词等相关属性
创建索引的时候,可以预先定义字段的类型以及相关属性,这样就能够把日期类型处理成日期,把数字字段处理成数字等。
测试:

GET lib/user/_mapping

结果是:

{
  "lib": {
    "mappings": {
      "user": {
        "properties": {
          "about": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "age": {
            "type": "long"
          },
          "first_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "interests": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "last_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

根据结果可以看到,每一个字段都被映射到了具体的数据类型(结果里type中的值就是数据类型)

ES支持的数据类型

ES可以根据给定的值自动进行数据类型的判断。

核心数据类型
  • 字符型 : String
    text和keyword
  1. text
    text类型被用来索引长文本,在建立索引前会将这些文本进行分词,转化为词的组合,建立索引。允许es来检索这些词语。text类型不能用来排序和聚合。
  2. keyword
    keyword类型不需要进行分词,可以被用来检索过滤,排序和聚合。keyword类型字段只能用本身来进行检索(因为不能进行分词,所以只能用本身来进行检索)。
  • 数字型:
    long,integer,short,byte,double,float
  • 日期型:
    date
  • 布尔型:
    boolean
  • 二进制型
    binary

分词的概念就是查询的时候只要用部分词进行查询就可以查询出来,简单来理解就是模糊查询。但是针对不分词的数据类型而言,如keyword,date,boolean,binary,数字型等,必须是精确查询,因为其不支持分词。
ES默认index时用standard+ngram分词器 。standard 分词器:(默认的)他会将词汇单元转换成小写形式,并去除停用词和标点符号,支持中文采用的方法为单字切分

复杂数据类型

支持数组类型,对象类型,嵌套类型

这里重点讲下对象类型。

es 大于 条件 es大于1_ES_04


如上图所示address是一个object对象类型。

对象类型在ES内部是怎么存储的?

es 大于 条件 es大于1_数据类型_05


上图就是对象类型的额存储格式,优点类似于json存储,对象.属性,以这种格式进行存储。

如果是更复杂一点的对象

es 大于 条件 es大于1_版本号_06


如上图所示,person是一个数组,每个数组的元素是一个对象类型,我们在底层存储的时候,会将相同的key提取出来,将值变为一个数组,所以就变成了上面的存储形式。

自己规定映射规则,动态创建

es 大于 条件 es大于1_字段_07


如上图所示,我们在settings属性中规定了其分片和副本数,在mappings中规定其相关属性,type指定映射的类型,analyzer指定了分词器的种类,index为false表示关闭倒排索引。ES会默认为我们的每一个字段添加倒排索引。若想关闭,需要指明其为false。属性的支持,下面会详细列举。

其他的类型

如地理类型,特定类型等。这里不做详细解释。

mapping支持的属性

es 大于 条件 es大于1_es 大于 条件_08