松哥原创的 Spring Boot 视频教程已经杀青,感兴趣的小伙伴戳这里-->Spring Boot+Vue+微人事视频教程
hello 各位小伙伴,Es 继续更新。从今天开始我们来看 Es 中常见的四种字段类型,由于这里涉及到的知识点比较多,因此松哥也录制了多个视频来讲解,每次两集,估计可以讲两次,今天我们先来学习核心类型和复合类型。
本文是ElasticSearch 系列第十二篇,和大家聊一聊索引的基本操作,前十一篇传送门:
- 
打算出一个 ElasticSearch 教程,谁赞成,谁反对? 
 - 
ElasticSearch 从安装开始 
 - 
ElasticSearch 第三弹,核心概念介绍 
 - 
ElasticSearch 中的中文分词器该怎么玩? 
 - 
ElasticSearch 索引基本操作 
 - 
ElasticSearch 文档的添加、获取以及更新 
 - 
ElasticSearch 文档的删除和批量操作 
 - 
ElasticSearch 文档路由,你的数据到底存在哪一个分片上? 
 - 
ElasticSearch 并发的处理方式:锁和版本控制 
 - 
ElasticSearch 中的倒排索引到底是什么? 
 - 
ElasticSearch 动态映射与静态映射 
 
核心类型:
核心类型(补充):
复合类型:
如果大家觉得视频风格还能接受,也可以看看松哥的付费视频:Spring Boot+Vue+微人事视频教程。
以下是视频笔记:
注意,笔记只是视频内容的一个简要记录,因此笔记内容比较简单,完整的内容可以查看视频。
10.1 核心类型
10.1.1 字符串类型
- 
string:这是一个已经过期的字符串类型。在 es5 之前,用这个来描述字符串,现在的话,它已经被 text 和 keyword 替代了。 
 - 
text:如果一个字段是要被全文检索的,比如说博客内容、新闻内容、产品描述,那么可以使用 text。用了 text 之后,字段内容会被分析,在生成倒排索引之前,字符串会被分词器分成一个个词项。text 类型的字段不用于排序,很少用于聚合。这种字符串也被称为 analyzed 字段。 
 - 
keyword:这种类型适用于结构化的字段,例如标签、email 地址、手机号码等等,这种类型的字段可以用作过滤、排序、聚合等。这种字符串也称之为 not-analyzed 字段。 
 
10.1.2 数字类型

- 
在满足需求的情况下,优先使用范围小的字段。字段长度越短,索引和搜索的效率越高。 
 - 
浮点数,优先考虑使用 scaled_float。 
 
scaled_float 举例:
PUT product
{
  "mappings": {
    "properties": {
      "name":{
        "type": "text"
      },
      "price":{
        "type": "scaled_float",
        "scaling_factor": 100
      }
    }
  }
}
10.1.3 日期类型
由于 JSON 中没有日期类型,所以 es 中的日期类型形式就比较多样:
- 
2020-11-11 或者 2020-11-11 11:11:11 
 - 
一个从 1970.1.1 零点到现在的一个秒数或者毫秒数。 
 
es 内部将时间转为 UTC,然后将时间按照 millseconds-since-the-epoch 的长整型来存储。
自定义日期类型:
PUT product
{
  "mappings": {
    "properties": {
      "date":{
        "type": "date"
      }
    }
  }
}
这个能够解析出来的时间格式比较多。
PUT product/_doc/1
{
  "date":"2020-11-11"
}
PUT product/_doc/2
{
  "date":"2020-11-11T11:11:11Z"
}
PUT product/_doc/3
{
  "date":"1604672099958"
}
上面三个文档中的日期都可以被解析,内部存储的是毫秒计时的长整型数。
10.1.4 布尔类型(boolean)
JSON 中的 “true”、“false”、true、false 都可以。
10.1.5 二进制类型(binary)
二进制接受的是 base64 编码的字符串,默认不存储,也不可搜索。
10.1.6 范围类型
- 
integer_range 
 - 
float_range 
 - 
long_range 
 - 
double_range 
 - 
date_range 
 - 
ip_range 
 
定义的时候,指定范围类型即可:
PUT product
{
  "mappings": {
    "properties": {
      "date":{
        "type": "date"
      },
      "price":{
        "type":"float_range"
      }
    }
  }
}
插入文档的时候,需要指定范围的界限:
PUT product
{
  "mappings": {
    "properties": {
      "date":{
        "type": "date"
      },
      "price":{
        "type":"float_range"
      }
    }
  }
}
指定范围的时,可以使用 gt、gte、lt、lte。
10.2 复合类型
10.2.1 数组类型
es 中没有专门的数组类型。默认情况下,任何字段都可以有一个或者多个值。需要注意的是,数组中的元素必须是同一种类型。
添加数组是,数组中的第一个元素决定了整个数组的类型。
10.2.2 对象类型(object)
由于 JSON 本身具有层级关系,所以文档包含内部对象。内部对象中,还可以再包含内部对象。
PUT product/_doc/2
{
  "date":"2020-11-11T11:11:11Z",
  "ext_info":{
    "address":"China"
  }
}
10.2.3 嵌套类型(nested)
nested 是 object 中的一个特例。
如果使用 object 类型,假如有如下一个文档:
{
  "user":[
    {
      "first":"Zhang",
      "last":"san"
    },
    {
      "first":"Li",
      "last":"si"
    }
    ]
}
由于 Lucene 没有内部对象的概念,所以 es 会将对象层次扁平化,将一个对象转为字段名和值构成的简单列表。即上面的文档,最终存储形式如下:
{
"user.first":["Zhang","Li"],
"user.last":["san","si"]
}
扁平化之后,用户名之间的关系没了。这样会导致如果搜索 Zhang si 这个人,会搜索到。
此时可以 nested 类型来解决问题,nested 对象类型可以保持数组中每个对象的独立性。nested 类型将数组中的每一饿对象作为独立隐藏文档来索引,这样每一个嵌套对象都可以独立被索引。
{
{
"user.first":"Zhang",
"user.last":"san"
},{
"user.first":"Li",
"user.last":"si"
}
}
优点
文档存储在一起,读取性能高。
缺点
更新父或者子文档时需要更新更个文档。

本文分享自微信公众号 - 江南一点雨(a_javaboy)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
