一起来学ElasticSearch(三)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 一起来学ElasticSearch(三)

前言

目前正在出一个Es专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~


承接上文,本节主要带大家学习ES Mapping,本期内容全是干货,好了, 废话不多说直接开整吧~


什么是Mapping

同样的,我们先讲基本概念,什么是mapping,上节给大家简要的举了一个例子,还有印象吗?mapping是es中一个比较重要的概念,如果这个搞不懂,下面的学习将会非常的困难。


我们说在关系型数据库中,比如mysql,在创建表的时候会对字段进行声明,赋予字段一些描述比如字段名称,类型等。


Es中同样的,我们之前讲Index的时候就给大家提到过,在创建文档的时候同样需要给文档进行字段声明,其中包括字段类型,是否分词,是否索引等一系列属性规则,而我们今天要讲的mapping就是提供这个作用的。


es中提供了动态mapping静态mapping两种方式来声明一个类型中文档的字段。

下面就给大家做一个详细的讲解~


Mapping 属性

mapping的属性,可以理解为一个type中,每个字段所具备的属性。下面给大家列一些常用的属性:


  • type: 字段类型,常用的有 text、integer 等等。


  • index: 默认true,字段是否建立倒排索引,false情况下不能被搜索,但支持聚合分析


  • enable: 默认true,字段是否建立倒排索引以及doc value,false情况下不能被搜索以及聚合,但是节约了内存空间


  • store: 默认false,字段是否额外存储,如果需要查询获取的字段只是文档中的小数据,这些字段可以store,减少IO。而且这个存储是独于 _source 的存储的。


  • doc_values: 默认true,优化字段排序聚合脚本访问,耗用磁盘空间


  • fields: 多字段特性。让一个字段拥有多个子字段类型,使得一个字段能够被多个不同的索引方式进行索引。


  • norms: 默认为true,是否支持评分,如果字段只用来过滤和聚合分析,而不需要被评分,那么可以设置为false;type 为 text 时,默认为 true;而 typekeyword 时,默认为 false。


  • analyzer: 指定索引和搜索时的分析器,如果同时指定 search_analyzer 则搜索时会优先使用 search_analyzer。


  • search_analyzer: 指定搜索时的分析器,搜索时的优先级最高。


  • fielddata: 默认false,针对text类型排序、聚合、脚本访问优化,尽量避免,操作昂贵


  • index_options: 用于设置倒排(索引)列表包含的信息,这些信息用于搜索(Search)和高亮显示:
  • docs:只索引文档编号(Doc Number);
  • freqs:索引文档编号和词频率(term frequency);
  • positions:索引文档编号,词频率和词位置(序号);
  • offsets:索引文档编号,词频率,词偏移量(开始和结束位置)和词位置(序号)。

默认情况下,被分词的字符串(analyzed string)字段使用 positions,其他字段默认使用 docs。


此外,需要注意的是 index_optionelasticsearch 特有的设置属性;临近搜索和短语查询时,index_option 必须设置为 offsets,同时高亮也可使用 postings highlighter。 记录内容越多,占用存储空间越大。


字段类型(type)详解

主要核心数据类型:


字符串类型

  • text

会做分词处理。类型为 text的字段可以通过全文检索搜索到。如果一个字段是要被全文搜索的,应该使用 text 类型。设置 text 类型以后,字段内容会被分析,在生成倒排索引以前,字符串会被分词器分成一个一个词条(term)。text 类型的字段不用于排序,且很少用于聚合(Terms Aggregation 除外)。


  • keyword

不会做分词处理。类型为 keyword 的字段只能通过精确值搜索到。类型适用于索引结构化的字段,通常用于过滤、排序、聚合


***PS:Elasticsearch 5.X 之后的字段类型不再支持 string,由 text 或 keyword 取代。如果仍使用 string,会给出警告。 ***


数字类型

  • byte: 取值范围 -128 至 127
  • short 取值范围 -32768 至 32767
  • integer 取值范围 -2^31 至 2^31-1
  • long    取值范围 -2^63 至 2^63-1
  • double  取值范围 64 位双精度 IEEE 754 浮点类型
  • float  取值范围 32 位单精度 IEEE 754 浮点类型
  • half_float  取值范围 16 位半精度 IEEE 754 浮点类型
  • scaled_float  取值范围  缩放类型的浮点数


这里需要注意的是,对于数字类型的字段,在满足需求的情况下,尽可能选择范围小的数据类型,好比人的年龄,最多就是三位数,使用short就完全能胜任,字段的长度越短,索引和搜索的效率越高


对于浮点数来说, 优先考虑使用 scaled_float 类型。scaled_float 是通过缩放因子把浮点数变成 long 类型,比如价格只需要精确到分,price 字段的取值为 57.34,设置放大因子为 100,存储起来就是 5734。所有的 API 都会把 price 的取值当作浮点数,事实上 Elasticsearch 底层存储的是整数类型,因为压缩整数比压缩浮点数更加节省存储空间


日期类型

  • date

ES 中的日期可以是以下几种形式:

  • 格式化日期的字符串,如 “2015-01-01” 或 “2015/01/01 12:10:30”
  • 毫秒时间戳
  • 秒级时间戳


需要注意的是,ES内部会把日期转换为 UTC(世界标准时间),并将其存储为毫秒时间戳,这样做的原因是和字符串相比,数值在存储和处理时更快。


布尔类型

  • boolean

如果一个字段是布尔类型,可接受的值为 true、false

***Elasticsearch 5.4 版本以前,可以接受被解释为 true 或 false 的字符串和数字,5.4 版本以后只接受 true、false、”true”、”false”。 ***


二进制类型

  • binary

binary 类型数据格式为base64 编码的字符串,默认不额外存储,也不可搜索


范围类型

  • range
  • integer_range -2^31 至 2^31-1
  • long_range -2^63 至 2^63-1
  • float_range 32-bit IEEE 754
  • double_range 64-bit IEEE 754
  • date_range 64 位整数,毫秒计时

复合数据类型

这个或许大家没有听过,它主要分为数组类型, 对象类型, 嵌套类型


数组类型

ES中没有专用的数组类型,默认情况下任何字段都可以包含0个或者多个值,但是一个数组中的值必须是同一种类型


  • 整型数组:[1,3]
  • 嵌套数组:[1,[2,3]],等价于 [1,2,3]
  • 对象数组: [{"name": "lili", "age": "18"}, {"name": "liming", "age": "20"} ]


动态添加数据时,数组的第一个值的类型决定整个数组的类型。 混合数组类型是不支持的,比如:[1,”abc”]。数组可以包含 null 值,空数组[ ]会被当作 missing field 对待。


在文档中使用 array 类型不需要提前做任何配置,默认支持。


对象类型

对象类型很好理解,即JSON对象,需要注意的是,es中会对嵌套的JSON对象做扁平化处理, 怎么理解呢?


例如如下数据:

{
  "name":"lili",
  "friend":[
    "name":"xiaohong"
  ]
}
复制代码


存储的时候变成这样:

{
  "name":"lili",
  "friend.name":"xiaohong"
}
复制代码


嵌套类型

嵌套类型是一种特殊的对象类型,es本身会对对象类型字段做扁平化处理,那么当存储的对象类型为对象数组时,会出现关联关系失效的情况

{
  "name":"lili",
  "friends":[
    {
      "name":"xiaohong",
      "age": 18
    },
    {
      "name":"xiaoming",
      "age": 20
    }
  ]
}
复制代码


处理后:

{
  "name":"lili",
  "friends.name":["xiaohong","xiaoming"],
  "friend.age":[18, 20]
}
复制代码


可以看出,数据直接的关联性没有了

如果需要索引对象数组并避免上述问题的产生,应该使用 nested 对象类型而不是 object 类型,nested 对象类型可以保持数组中每个对象的独立性。Nested 类型将数组中每个对象作为独立隐藏文档来索引,这意味着每个嵌套对象都可以独立被搜索

为了防止过度定义嵌套字段的数量,每个索引可以定义的嵌套字段被限制在 50 个


地理数据类型

地理相关类型有地理坐标类型(geo_point)地理图形类型(geo_shape)


地理坐标(geo_point)类型

geo point 类型用于存储地理位置信息的经纬度,可用于以下几种场景:

  • 查找一定范围内的地理位置。
  • 通过地理位置或者相对中心点的距离来聚合文档。
  • 把距离因素整合到文档的评分中。
  • 通过距离对文档排序。
  • 存储格式: 经纬度JSON格式:{“lat”:41.12,”lon”:-71.34}
  • 经纬度字符串格式:"41.12,-71.34"
  • 地理坐标hash值:"u1269qu5dcgp"
  • 经纬度数组形式:[41.12,-71.34]


地理图形(geo_shape)类型

这个不跟大家介绍了,不常用,它的存储形式是geoJson,如下形式:

{
 "type":"Point",
 "coordinates":[
     100,
     0
 ]
}
复制代码


特殊类型

IP类型 (ip)

ip 类型的字段用于存储 IPv4 或者 IPv6 的地址。如”192.168.1.1”或”192.168.0.0/16”


令牌计数类型 (token_count)

token_count 用于统计text分词后的词条个数,本质上是一个整数型字段。举个例子,映射中指定 name 为 text 类型,增加name.length 字段用于统计分词后词项的长度,类型为 token_count,分词器为标准分词器,命令如下:

{
  "mappings": {
    "my_type": {
      "properties": {
        "name": {
          "type": "text",
          "fields": {
            "length": {
              "type": "token_count",
              "analyzer": "standard"
            }
          }
        }
      }
    }
  }
}
复制代码


结束语

本节主要讲了ES中的mapping概念以及它的基础属性,以及给大家介绍了常用的核心数据类型,本节理论偏多点,所以需要大家动手去消化一下,光看很容易忘记,动手实践印象会更深。正确的使用类型,可以帮助我们更好的解决问题,也可以帮我们节约服务器成本。本节还遗留一些东西,放到下节给大家讲,下节给大家说说什么是动态mapping

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
存储 搜索推荐 关系型数据库
为什么需要 Elasticsearch
为什么需要 Elasticsearch
21 0
|
3月前
|
搜索推荐 关系型数据库 MySQL
【Elasticsearch】初识elasticsearch
【Elasticsearch】初识elasticsearch
41 1
|
5月前
|
搜索推荐 Java Apache
ElasticSearch
ElasticSearch
44 0
|
7月前
Elasticsearch应用详解
Elasticsearch应用详解
24 0
|
8月前
|
存储 缓存 索引
Elasticsearch(四)
Elasticsearch(四)
33 0
|
8月前
|
存储 关系型数据库 MySQL
Elasticsearch(一)
Elasticsearch(一)
41 0
|
10月前
|
存储 JSON 自然语言处理
【Elasticsearch】初识elasticsearch(下)
【Elasticsearch】初识elasticsearch(下)
48 0
|
10月前
|
存储 监控 搜索推荐
【Elasticsearch】初识elasticsearch(上)
【Elasticsearch】初识elasticsearch
53 0
|
12月前
|
前端开发 Java API
一起来学ElasticSearch(十)
前言 目前正在出一个Es专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~ 承接上文,上节给大家讲的es聚合还有一点内容,本节给大家更完~ 本文偏实战一些,为了方便演示,本节示例沿用上节索引,好了, 废话不多说直接开整吧~ 聚合排序 我们如何在聚合结果中进行自定义字段排序呢?
|
自然语言处理 索引
如果还不会Elasticsearch这七个问题 那么你的Elasticsearch白学
如果还不会Elasticsearch这七个问题 那么你的Elasticsearch白学
56 0