ElasticSearch Mapping数据类型、主要参数一览

ElasticSearch 数据类型

类型一览表

一级分类二级分类具体类型使用
核心类型字符串类型string,text,keyword结构化搜索,全文文本搜索、聚合、排序等
整数类型integer,long,short,byte字段的长度越短,索引和搜索的效率越高。
浮点类型double,float,half_float,scaled_float
逻辑类型boolean
日期类型date
范围类型range
二进制类型binary
复合类型数组类型array
对象类型object
嵌套类型nested
地理类型地理坐标类型geo_point
地理地图geo_shape
特殊类型IP类型ip
范围类型completion
令牌计数类型token_count
附件类型attachment
抽取类型percolator

文本类型

text 全文类型

  • description
    用于索引全文值的字段。使用文本数据类型的字段,它们会被分词,在索引之前将字符串转换为单个术语的列表(倒排索引),分词过程允许ES搜索每个全文字段中的单个单词。文本字段不用于排序,很少用于聚合(重要的术语聚合是一个例外)。什幺情况适合使用text datatype,只要不具备唯一性的字符串一般都可以使用text,例如:电子邮件正文,商品介绍,个人简介
  • parameter
  1. analyzer:指明该字段用于索引时和搜索时的分析字符串的分词器(使用search_analyzer可覆盖它)。 默认为索引分析器或标准分词器
  2. fielddata:指明该字段是否可以使用内存中的fielddata进行排序,聚合或脚本编写?默认值为false,可取值true或false。(排序,分组需要指定为true)
  3. fields:【多数类型】text类型字段会被分词搜索,不能用于排序,而当字段既要能通过分词搜索,又要能够排序,就要设置fields为keyword类型进行聚合排序。
  4. index:【是否被索引】设置该字段是否可以用于搜索。默认为true,表示可以用于搜索。
  5. search_analyzer:设置在搜索时,用于分析该字段的分析器,默认是【analyzer】参数的值。
  6. search_quote_analyzer:设置在遇到短语搜索时,用于分析该字段的分析器,默认是【search_analyzer】参数的值。
  7. index_options:【索引选项】用于控制在索引过程中哪些信息会被写入到倒排索引中
    • docs:只索引文档号到倒排索引中,但是并不会存储
    • freqs:文档号和关键词的出现频率会被索引,词频用于给文档进行评分,重复词的评分会高于单个次评分
    • positions:文档号、词频和关键词 term 的相对位置会被索引,相对位置可用于编辑距离计算和短语查询(不分词那种)
    • offsets:文档号、词频、关键词 term 的相对位置和该词的起始字符串偏移量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I265lsjS-1599834691551)(en-resource://database/2637:1)]

首先创建 test_index 索引,设置其字段为全文类型,并设置其索引选项为 offsets ,即索引其偏移量

PUT test_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "index_options": "offsets"
      }
    }
  }
}

test_index 索引存储一条数据,该条文本会根据其默认的分词器 standard 分词器将其进行索引

PUT test_index/_doc/1
{
  "text": "Quick brown fox"
}

使用全文搜索 match 方法进行搜索,并高亮显示 text 属性,效果如下图,当然如果在Kibana的Discovery中会有高亮显示

GET test_index/_search
{
  "query": {
    "match": {
      "text": "brown fox"
    }
  },
  "highlight": {
    "fields": {
      "text": {}  // text 字段将会被高亮,如下图所示,因为其offsets已经被索引
    }
  }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c4eObRkI-1599834691556)(en-resource://database/4294:1)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5F9ontJs-1599834691561)(en-resource://database/2639:1)]

PUT test_index
{
    "mappings": {
        "properties": {
            "title":{
                "type": "text",
                "analyzer": "standard",
                "fielddata": true, # 全文类型聚合的话需要开启这个字段
                "fields": {
                    "sort":{
                        "type": "keyword"
                    }
                },
                "index": true,
                "search_analyzer": "standard"
            }
        }
    }
}

#插入两条数据,测试一下
 PUT test_index/_doc/1
 {"title": "York"}
 PUT test_index/_doc/2
 {"title": "NEW York"}


#查询测试
GET test_index/_search
{
    "query": {
        "match": {
            "title": "york"
        }
    },
    "sort": {
        "title.sort": "asc"
    }
}

keyword 关键字数据类型

keyword datatype,关键字数据类型,用于索引结构化内容的字段。使用keyword类型的字段,其不会被分析,给什幺值就原封不动地按照这个值索引,所以关键字字段只能按其确切值进行搜索,通常用于过滤、排序和聚合。什幺情况下使用keyword datatype,具有唯一性的字符串,例如:电子邮件地址、MAC地址、身份证号、状态代码…

  1. eager_global_ordinals:指明该字段是否加载全局序数?默认为false,不加载。 对于经常用于术语聚合的字段,启用此功能是个好主意。
  2. fields:指明能以不同的方式索引该字段相同的字符串值,例如用于搜索的一个字段和用于排序和聚合的多字段
  3. ignore_above:不要索引长于此值的任何字符串。默认为2147483647,以便接受所有值
  4. index:指明该字段是否可以被搜索,默认为true,表示可以被搜索
  5. index_options:指定该字段应将哪些信息存储在索引中,以便用于评分。默认为docs,但也可以设置为freqs,这样可以在计算分数时考虑术语频率
  6. norms:在进行查询评分时,是否需要考虑字段长度,默认为false,不考虑
  7. ignore_above:默认值是256,该参数的意思是,当字段文本的长度大于指定值时,不会被索引,但是会存储。即当字段文本的长度大于指定值时,聚合、全文搜索都查不到这条数据。ignore_above 最大值是 32766 ,但是要根据场景来设置,比如说中文最大值 应该是设定在10922

    ignore_above背后的含义:Lucene对一个文本长度进行解析,当这个长度大于32766时,将不会进行analye行为。elasticsearch中采用字符个数来定义ignore_above值,而 Lucene 是采用byte字节。

    • 象形文字字符(中文、韩文、日文): 10922 个字符(算法是: 32766 / 3).
    • Literal字符(印度问、俄文): 16383 个字符(算法是: 32766 / 2).
    • ASCII字符(a-zA-Z0-9以及~!@#$等特殊字符): 32766个字符(算法是: 32766).
PUT test_index
{
   "mappings": {
       "properties": {
           "title":{
               "type": "keyword",
               "eager_global_ordinals": true,
               "fields": {
                   "sort":{
                       "type":"text"
                   }
               },
               "ignore_above": 1024,
               "index": true,
               "index_options": "freqs",
               "norms": true
           }
       }
   }
}

数字类型

ES支持的数字类型有整型数字类型,integer类型、long类型、short类型、byte类型。浮点型数字类型 double类型、 float类型、 half_float类型、 scaled_float类型这类数据类型都是以确切值索引的,可以使用term查询精确匹配。

  • long带符号的64位整数,最小值-263,最大值263-1
  • integer带符号的32位整数,最小值-231,最大值231^-1
  • short带符号的16位整数,最小值-32768,最大值32767
  • byte带符号的8位整数,最小值-128,最小值127
  • double双精度64位IEEE 754 浮点数
  • float单精度32位IEEE 754 浮点数
  • half_float半精度16位IEEE 754 浮点数
  • scaled_float带有缩放因子的缩放类型浮点数,依靠一个long数字类型通过一个固定的(double类型)缩放因数进行缩放.
PUT test_index
{
    "mappings": {
        "properties": {
            "number1":{
                "type": "long"
            },
            "number2":{
                "type": "integer"
            },
            "number3":{
                "type": "short"
            },
            "number4":{
                "type": "byte"
            },
            "number5":{
                "type": "double"
            },
            "number6":{
                "type": "float"
            },
            "number7":{
                "type": "half_float"
            },
            "number8":{
                "type": "scaled_float",
                "scaling_factor": 100 #缩放因子为100,是一个浮点数
            }
        }
    }
}

parameter

  1. coerce:是否尝试将字符串转换为整数并截断整数的分数,默认为true,接受一个boolean值
  2. boost:
  3. doc_values:是否将该字段以逐列的方式存储在磁盘上,用于聚合和排序,默认true
  4. store:字段是否与_source元数据分开存储
  5. meta:关于字段的元数据,附加到字段上
  6. ignore_malformed:如果为true,则忽略格式错误的数字;如果为false则格式错误的数字会抛出异常并拒绝整个文档,默认false
  7. index:指明该字段是否被搜索。默认为true,表示可以被搜索
  8. null_value:指明一个与该字段相同类型的值去替换掉该字段中的null。默认为null,表示该字段被视为缺失
  9. scaled_float类型接受一个附加参数scaling_factor

浮点型数据类型(double、float、half_float),认为-0.0和0.0是不同的值。这意味着在-0.0上进行查询(match or term)匹配不到0.0,反之亦然;范围查询也是如此:如果上限为-0.0则0.0将不匹配,如果下限为0.0则-0.0将不匹配。

整数类型(byte,short,integer和long),要选择满足实际需求的最小类型,这有助于索引和搜索。但请注意:ES存储数据是根据存储的实际值进行优化的,因此选择一种类型而不是另一种类型,将不会影响存储要求。

scaled_float类型需要注意:
scaled_float类型需要格外注意:必须指定缩放因子scaling_factor。
ES索引时,原始值会乘以该缩放因子并四舍五入得到新值,ES内部储存的是这个新值,但返回结果仍是原始值。
例如:scale_factor为10,ES在索引时,的scaled_float字段将在内部存储2.34为23,
查询时,ES都会将查询参数x10再四舍五入得到的值与23匹配,若能匹配到返回结果为2.34

# 先创建一个缩放的索引
PUT test_index?pretty
{
  "mappings": {
    "properties": {
      "scaled_numeric": {
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }
  }
}

#添加两条数据

#21.2121*100四舍五入得到2121储存结果
#21.2155*100四舍五入得到2122储存结果
POST test_index/_doc
{
  "scaled_numeric": 21.2121
}
POST test_index/_doc
{
  "scaled_numeric": 21.2155
}
#查询测试
#21.2133*100四舍五入得到2121匹配上面插入的_id=1的数据
#21.2199*100四舍五入得到2122匹配上面插入的_id=2的数据
GET test_index/_search
{
  "query": {
    "match": {
      "number8": 21.2133
    }
  }
}
GET test_index/_search
{
  "query": {
    "match": {
      "number8": 21.2199
    }
  }
}

日期类型

日期数据类型。
由于JSON中没有表示日期的数据类型,所以ES中的日期可以表示为:

日期格式化后的字符串,如:”2018-01-01″或”2018/01/01 11:11:11″
long类型值表示自纪元以来的毫秒数
integer类型值表示自纪元以来的秒数
如果指定了时区,ES将日期转换为UTC,然后再存储为自纪元以来的毫秒数(long类型)。
当字段被设置为date类型时,可以自定义日期格式,但如果未指定格式,则使用默认格式:”strict_date_optional_time||epoch_millis”
若未指定自定义日期格式,在保存日期的时候容易出错。若未指定日期格式,ES采用默认日期格式:严格日期格式或者时间戳,
例如:

2020-01-01 —- yes
2020/01/01 —- no
2020-01-1 —- no
1577808000000 —- yes
在使用date类型字段进行排序时,返回的排序值都是以毫秒为单位

parameter

  1. format:自定义的日期格式,默认:strict_date_optional_time || epoch_millis
  2. ignore_malformed:若为true,则忽略格式错误的数字;若为false,则格式错误的数字会抛出异常并拒绝整个文档。默认false
  3. index:指明该字段是否可以被搜索,true为可以,默认true
  4. null_value:接受其中一个配置格式的日期值作为替换任何显式空值的字段。默认为null,表示该字段被视为缺失
PUT test_index
{
  "mappings": {
    "properties": {
      "date1": {
        "type": "date"
      },
      "date2": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "date3": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||yyyy/MM/dd||epoch_millis"
      }
    }
  }
}
#添加2条数据
POST test_index/_doc
{
  "dateTimeFormat": "2015-01-01 12:10:30"
}


PUT test_index/_doc/1
{
  "date1": 1577808000000,
  "date2": "2020-01-01 00:00:00",
  "date3": "2020/01/01"
}
PUT test_index/_doc/2
{
  "date1": 1577808000001,
  "date2": "2020-01-01 00:00:01",
  "date3": "2020/01/01"
}
#查询测试
GET test_index/_search
{
  "sort": [
    {
      "date2": {
        "order": "desc"
      }
    }
  ]
}

范围类型

范围数据类型。具有大小关系的一个值区间,所以会用到gt、gte、lt、lte…等逻辑表示符。
ES支持下面6种范围数据类型

integer_range,带符号的32位整数区间,最小值-231,最大值231-1
long_range,带符号的64位整数区间,最小值-263,最小值263-1
float_range,单精度32位IEEE 754浮点数区间
double_range,双精度64位IEEE 754浮点数区间
date_range,日期值范围,表示为系统纪元以来经过的无符号64位整数毫秒
ip_range,支持IPv4或IPv6(或混合)地址ip值范围

PUT test_index
{
  "mappings": {
    "properties": {
      "data1": {
        "type": "integer_range"
      },
      "data2": {
        "type": "float_range"
      },
      "data3": {
        "type": "date_range",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "data4": {
        "type": "ip_range"
      }
    }
  }
}

开始添加数据

PUT test_index/_doc/1
{
  "date1": {
    "gte": 100,
    "lte": 200
  },
  "date2": {
    "gte": 21.21,
    "lte": 22
  },
  "date3": {
    "gte": "2020-01-01 00:00:00",
    "lte": "2020-01-02 00:00:00"
  },
  "date4": {
    "gte": "192.168.192.10",
    "lte": "192.168.192.11"
  }
}

查询测试

GET test_index/_search

数组类型

数组类型。默认情况下,任何字段都可以包含零个或多个值,当包含多个值时,它就表示array datatype了。但是,数组中的所有值必须具有相同的数据类型(要幺同为字符串,要幺同为整型,不能数组中一些值为字符串,另一些值为整型)

当数组里面放的是对象(object datatype),即对象数组时,要改为使用nested datatype。

在动态添加字段时,ES从数组中的第一个值确定字段类型,所有后续值必须具有相同的数据类型,或者必须至少可以将后续值强制转换为相同的数据类型。

使用array datatype,不需要预先配置,它们是开箱即用的。(不像整型,它需要手动定义type: “integer”)

使用_mapping查看索引的映射类型时,array datatype不会被写出来,还是以数组的元素的基本类型来表示。

PUT test_index
{
  "mappings": {
    "properties": {
      "data1": {
        "type": "long"
      },
      "data2": {
        "type": "text"
      }
    }
  }
}
#添加数据
PUT test_index/_doc/1
{
  "date1": [
    1,
    2,
    3
  ],
  "date2": [
    "a",
    "b",
    "c"
  ]
}
#查询测试
GET test_index/_search

对象类型

即对象类型。一个文档的一个属性可以是一个内部对象,而且,这个内部对象,可以再包含一个内部对象…(可以有多层嵌套)

整个外部文档是一个JSON对象
在ES内部,这种文档会被索引成一种简单平坦的键值对列表(平铺)

PUT test_index
{
  "mappings": {
    "properties": {
      "persion": {
        "type": "object"
      }
    }
  }
}

PUT test_index/_doc/1
{
  "persion": [
    {
      "first": "li",
      "last": "si"
    },
    {
      "first": "李",
      "last": "四"
    }
  ]
}
PUT test_index/_doc/2
{
  "persion": [
    {
      "first": "li",
      "last": "四"
    },
    {
      "first": "李",
      "last": "si"
    }
  ]
}
#查询测试1
GET test_index/_search
无法做到对象中数组独立索引和查询

#查询测试
GET test_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "persion.first": "li"
          }
        },
        {
          "match": {
            "persion.last": "si"
          }
        }
      ]
    }
  }
}

出现问题,不正确的匹配。使用nested嵌套对象类型解决

原因:对象类型里的数组类型会将字段平铺为多值字段,因此 li si 之间的关联关系会消失,会将上面的文档转换成如下格式:

{
persion.first:["li 李"]
persion.last:["四 si"]
}

嵌套对象类型

嵌套数据类型,是object datatype的专用版本,在文档属性是一个对象数组时使用,它允许对象数组彼此独立地编制索引和查询

PUT test_index
{
  "mappings": {
    "properties": {
      "persion": {
        "type": "nested"
      }
    }
  }
}
#添加数据
PUT test_index/_doc/1
{
  "persion": [
    {
      "first": "li",
      "last": "si"
    },
    {
      "first": "李",
      "last": "四"
    }
  ]
}
PUT test_index/_doc/2
{
  "persion": [
    {
      "first": "li",
      "last": "四"
    },
    {
      "first": "李",
      "last": "si"
    }
  ]
}
#查询测试
GET test_index/_search
{
  "query": {
    "nested": {
      "path": "persion",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "persion.first": "li"
              }
            },
            {
              "match": {
                "persion.last": "si"
              }
            }
          ]
        }
      }
    }
  }
}

地理类型

地址位置数据类型,可以用来表示经纬度。

PUT test_index
{
  "mappings": {
    "properties": {
      "add": {
        "type": "geo_point"
      }
    }
  }
}

地理点表示为一个对象,lat属性表示维度,lon属性表示经度

PUT test_index/_doc/1
{
  "add": {
    "lat": 22.22,
    "lon": -22.22
  }
}

地理点表示为一个字符串,格式为:”lat,lon”

PUT test_index/_doc/2
{
"add": "22.22,-22.22"
}

地理点表示为一个geohash字符串

PUT test_index/_doc/3
{
"add": "eebnqm5bukpn"
}

地理点表示为一个数组,格式为[lon,lat],注意经纬度顺序字符串标识相反

PUT test_index/_doc/4
{
  "add": [
    -22.22,
    22.22
  ]
}

参考资料

ignore_above:https://www.jianshu.com/p/4e336b760070

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜马拉雅以南

奶茶,干杯?!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值