引言:上一节,我们学习了ES的基本概念和ES的数据架构【关注公众号:ZeroTeHero,获取上节内容】。今天,TeHero将为大家讲解ES的数据类型。

数据的存储,都是需要预先确定好数据的类型的,不管是关系型数据库mysql还是非关系型数据库MongoDB,都有一套数据类型系统(两者很类似,但也有区别)。那么ES的数据类型有哪些呢?TeHero为你倾情讲解^~^。

ES的数据类型汇总

ES数据类型汇总图(注意标红的类型)

从上图可以看到ES的数据类型和mysql或MongoDB的是很相似的,所以对于有数据结构基础的伙伴,这个知识点是非常轻松的。

TeHero将详细为大家介绍上图中标红的4种数据类型(数值类型就很一目了然)【ps:如果你还想了解其他的类型,可以直接进ES的官网阅读】,让大家在以后的工作中能熟练使用,知道什么时候该用哪种类型,该怎么用。

一、String 类型

String类型可以和java的string、mysql的varchar等同,但是为何会分为text、keyword呢?这两者又有什么区别?

ES作为全文检索引擎,它强大的地方就在于分词和倒排序索引。而 text 和 keyword 的区别就在于是否分词(ps:什么叫分词?举个简单例子,“中国我爱你”这句话,如果使用了分词,那么这句话在底层的储存可能就是“中国”、“我爱你”,被拆分成了两个关键字),分词后面TeHero会专门写文章进行讲解,敬请期待哟。【关注公众号:ZeroTeHero,获取最新文章推送

1)text——会分词

就拿刚才的例子来说,“中国我爱你”这句话,如果使用text类型储存,我们不去特殊定义它的分词器,那么ES就会使用默认的分词器 standard 。

ES的分词器(可先有个概念)

下图就是“中国我爱你”的ES分词效果:

这意味着什么呢?如果你使用text类型去储存你本不想分词的string类型,你在查询的时候,查询结果将违背你的预期。

简单看个示例:

# 创建索引
PUT /toherotest
{"mappings": {"_doc":{"properties" : {"field1" : { "type" : "text" }}}}
}
# 存入数据
POST /toherotest/_doc/1
{"field1":"中国我爱你"
}

# 查询 索引下的所有数据
GET /toherotest/_doc/_search

条件查询,等价于mysql的 where field1 = "中国我爱你" 。发现居然查询不到

GET /toherotest/_doc/_search
{"query": {"term": {"field1": {"value": "中国我爱你"}}}
}

再根据刚才的ES分词效果,我们检索其中一个字,居然神奇的检索到了

GET /toherotest/_doc/_search
{"query": {"term": {"field1": {"value": "中"}}}
}

这是为什么呢?我们发现在使用term查询(等价于mysql的=)时却查不到结果,其实就是因为text类型会分词,简单理解就是“中国我爱你”这句话在ES的倒排序索引中存储的是单个字,所以无法检索。

2)keywor——不会分词

我们新增一个keyword类型的字段field2,再来看看检索效果:

# 测试分词效果
GET /_analyze
{"text": ["中国我爱你"],"analyzer": "keyword"
}
# 结果
{"tokens": [{"token": "中国我爱你","start_offset": 0,"end_offset": 5,"type": "word","position": 0}]
}# 新增 字段类型 keyword
PUT toherotest/_mapping/_doc
{"properties": {"field2": {"type": "keyword"}}
}
# 新增数据
PUT /toherotest/_doc/12
{"field2":"中国我爱你"
}
# 查询
GET /toherotest/_doc/_search
{"query": {"term": {"field2": {"value": "中国我爱你"}}}
}

可以发现,类型为keyword,通过term是可以查询到,说明ES对keyword是没有分词的。

二、date 时间类型 —— 可规定格式

对于date类型,和mysql的几乎一样,唯一的注意点就是,储存的格式,ES是可以控制的。

PUT my_index
{"mappings": {"_doc": {"properties": {"date": {"type": "date" }}}}
}PUT my_index/_doc/1
{ "date": "2015-01-01" } PUT my_index/_doc/2
{ "date": "2015-01-01T12:10:30Z" } PUT my_index/_doc/3
{ "date": 1420070400001 } GET my_index/_search
{"sort": { "date": "asc"}
}

大家可以用kibana试试,3种格式都可以的。同时ES的date类型允许我们规定格式,可以使用的格式有:

yyyy-MM-dd HH:mm:ss

yyyy-MM-dd

epoch_millis(毫秒值)

# 规定格式如下: || 表示或者
PUT my_index
{"mappings": {"_doc": {"properties": {"date": {"type":   "date","format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"}}}}
}

注意:一旦我们规定了格式,如果新增数据不符合这个格式,ES将会报错mapper_parsing_exception。

三、复杂类型

ES的复杂类型有3个,Array、object、nested。

1)Array:在Elasticsearch中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值都必须具有相同的数据类型。

举个简单例子理解下:比如上一个例子中的field1这个字段,可以只存储一个值“中国我爱你”,同时也可以存储一个数组:["这是","一个","数组"]

# 新增数据
POST /toherotest/_doc/2
{"field1":["这是","一个","数组"]
}

2)object:我相信大家都能理解;需要注意的是,object类型的字段,也可以有多个值,形成List<object>的数据结构

重点:List<object>中的object不允许彼此独立地索引查询。这是什么意思呢?

举个简单例子:我们现在有2条数据:数据结构都是一个List<object>

# 第一条数据:[ { "name":"tohero1", "age":1 }, { "name":"tohero2", "age":2 } ]

# 第二条数据:[ { "name":"tohero1", "age":2 }, { "name":"tohero2", "age":1 } ]

如果此时我们的需求是,只要 name = “tohero1”and “age”= 1 的数据,根据我们常规的理解,只有第一条数据才能被检索出来,但是真的是这样么?我们写个例子看看:

# 添加 属性为object的字段 field3
PUT toherotest/_mapping/_doc
{"properties": {"field3": {"type": "object"}}
}
# 新增数据
POST /toherotest/_doc/3
{"field3":[ { "name":"tohero1", "age":1 }, { "name":"tohero2", "age":2 } ]
}POST /toherotest/_doc/4
{"field3": [ { "name":"tohero1", "age":2 }, { "name":"tohero2", "age":1 } ]
}#执行查询语句
GET /toherotest/_doc/_search
{"query": {"bool": {"must": [{"term": {"field3.name": "tohero1"}},{"term": {"field3.age": 1}}]}}
}

(ps:现在看不懂查询语句,没关系,主要是理解几个类型的差异,可以后面学了查询语句再回头看查询语句)查询语句等价于mysql的 where name = “tohero1”and “age”= 1

查询结果如下:

{"took": 2,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 2,"max_score": 1.287682,"hits": [{"_index": "toherotest","_type": "_doc","_id": "4","_score": 1.287682,"_source": {"field3": [{"name": "tohero1","age": 2},{"name": "tohero2","age": 1}]}},{"_index": "toherotest","_type": "_doc","_id": "3","_score": 1.287682,"_source": {"field3": [{"name": "tohero1","age": 1},{"name": "tohero2","age": 2}]}}]}
}

可以看到两条数据都被我们检索到了。所以,现在理解什么叫做“object不允许彼此独立地索引查询”了吧。

但是,我们在日常的使用过程中,常规的需求就是,希望object能被独立的索引,难道es满足不了这个需求么?那是不可能。下面就来看下nested类型。

3)nested 类型

需要建立对象数组的索引并保持数组中每个对象的独立性,则应使用nested数据类型而不是 object数据类型。在内部,嵌套对象索引阵列作为一个单独的隐藏文档中的每个对象,这意味着每个嵌套的对象可以被独立的查询。

备注:关于nested类型,TeHero在此就不写实例了,因为对于nested的应用本身属于ES的高级操作,后面TeHero会单独出一期关于nested的使用教程。【关注公众号:ZeroTeHero,获取最新文章推送】

对于复杂类型,目前先知道 object和nested类型的区别即可。

三、GEO 地理位置类型

对于 GEO 地理位置类型,分为 地图:Geo-point 和 形状 :Geo-shape,两种数据类型。

对于web开发,一般常用的是 地图类型 Geo-point。

要求:先知道如何定义,如何查询即可

新建索引和创建  geo_point 字段:

# 新建一个索引,创建类型为地图的字段location
PUT my_index
{"mappings": {"_doc": {"properties": {"location": {"type": "geo_point"}}}}
}# 新增数据 经纬度方式
PUT my_index/_doc/1
{"text": "Geo-point as an object","location": { "lat": 41.12,"lon": -71.34}
}PUT my_index/_doc/2
{"text": "Geo-point as a string","location": "41.12,-71.34"
}PUT my_index/_doc/3
{"text": "Geo-point as a geohash","location": "drm3btev3e86"
}PUT my_index/_doc/4
{"text": "Geo-point as an array","location": [ -71.34, 41.12 ]
}

距离查询:距离某个点方圆200km

GET /my_locations/_search
{"query": {"bool" : {"must" : {"match_all" : {}},"filter" : {"geo_distance" : {"distance" : "200km","pin.location" : {"lat" : 40,"lon" : -70}}}}}
}

到此,ES的数据类型就讲解完了。里面的DSL语句如果看不懂,没关系!通过本文章的学习,你知道了ES有哪些数据类型,这3个重点类型的注意点、使用区别和场景,就足够了。

下期预告:ES索引和文档的 CRUD 操作【关注公众号:ZeroTeHero,获取最新文章推送】

ElasticSearch系列03:ES的数据类型相关推荐

  1. 【ElasticSearch系列】ES简介及安装

    [前提:] 目前大部分的数据库在提取数据方面是非常薄弱的,虽然它们可以通过时间戳或相关的数值来进行内容的筛选,但是它们无法在全文搜索的同时做到同义词或相关性的搜索,它们也无法获取相同内容的数据.这个看 ...

  2. 【ElasticSearch系列】ES插件安装

    上篇文章介绍了一下EleasticSearch以及安装,这篇文章继续,将介绍ES的插件安装. 其实最开始我也不知道要安装什么插件,其实也疑惑,为什么ES不将需要的插件集成到自身,这样就能避免很多问题. ...

  3. ElasticSearch系列18:Mapping 设计指南

     点击上方"方才编程",即可关注我! 本文导读 ElasticSearch 的 mapping 该如何设计,才能保证检索的高效?想要回答这个问题,就需要全面系统地掌握 mappin ...

  4. ElasticSearch系列 - SpringBoot整合ES:多个精确值查询 terms

    文章目录 01. ElasticSearch terms 查询支持的数据类型 02. ElasticSearch term和 terms 查询的区别 03. ElasticSearch terms 查 ...

  5. 【ElasticSearch系列连载】3. 如何安装符合生产环境要求的ES集群

    [ElasticSearch系列连载]3. 如何安装符合生产环境要求的ES集群 通过本文,将会循序渐进地了解到ES的若干部署方案,以及相关的基础操作与配置. 上一节介绍的一键安装方式,可以快速启动一个 ...

  6. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例

    转载自  Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 第1部分 ArrayList介绍 ArrayList简介 ArrayList 是一个数组队列,相当于 动态数组.与 ...

  7. 2Python全栈之路系列之MysQl基本数据类型

    Python全栈之路系列之MySQL基本数据类型 MySQL中定义数据字段的类型对你数据库的优化是非常重要的. MySQL支持多种类型,大致可以分为三类: 数字类型 日期和时间类型 字符串类型 数字类 ...

  8. ElasticSearch系列——Kibana,核心概念

    ElasticSearch系列--Kibana,核心概念 Kibana 下载地址 Windows安装 修改配置文件 启动Kibana 验证 ES核心概念 Index索引 Mapping映射 Docum ...

  9. 【Python零基础快速入门系列 | 03】AI数据容器底层核心之Python列表

    • 这是机器未来的第7篇文章 原文首发地址:https://blog.csdn.net/RobotFutures/article/details/124957520 <Python零基础快速入门 ...

最新文章

  1. RecyclerView上拉加载Demo
  2. 通过GeoIP2分析访问者IP获取地理位置信息
  3. Android华容道之一步一步实现-4-图像块移动算法
  4. Python Django 多表插入之重写save()方法代码示例
  5. Angular Jasmine 里一些常用概念学习笔记 - describe, it, beforeEach的用法
  6. Transact-SQL数据类型(文本/图形/日期和时间/货币/特定类型)
  7. zookeeper配置集群
  8. Vertically aligning HTML
  9. No package ‘polkit-gobject-1‘ found
  10. Windows驱动开发(中间层)
  11. Linux实战之ssl自签名证书
  12. 【JavaWeb】石家庄地铁搭乘系统——第二版
  13. springboot集成ueditor百度富文本编辑器及上传图片到oss服务器
  14. 苹果电脑开机长android,苹果笔记本开机白屏时间太长
  15. 野蛮时代SLG数据分析报告
  16. Mac清理系统用什么软件?
  17. [RK3288][Android6.0] WiFi之cfg80211知识点小结
  18. 阶层是一条漫长的阶梯,你能爬到第几层?
  19. 下雨天客流量少,美容院怎么做生意
  20. BIND的进阶二:视图,日志,转发,子域的授权

热门文章

  1. 制定项目章程-规划过程组
  2. 【学生必备求职指南】好简历是怎样炼成的?毕业生简历实例点评版
  3. 金蝶采购模块退货业务标准流程
  4. 敲代码时如何快速移动光标_HTML网页代码大全
  5. XP下让系统自动登录
  6. 【LeetCode系列】最长回文子串(双指针中心扩散)与可怜的小猪(老鼠毒药问题)
  7. 赛扬处理器_神舟推出优雅X4D2轻薄本,搭载赛扬处理器
  8. 人关节软骨细胞的体外培养
  9. Bear Rallies Turn Market Into a Circus
  10. tradingview 修改K线的颜色,边框色,线条色