写在前面:我是「且听风吟」,目前是一名大数据开发工程师,热爱大数据开源技术,喜欢分享自己的所学所悟,现阶段正在从头梳理大数据体系的知识,以后将会把时间重点放在Spark和Flink上面。

如果你也对大数据感兴趣,希望在这个行业一展拳脚。欢迎关注我,我们一起努力,一起学习。博客地址:https://ropledata.blog.csdn.net

博客的名字来源于:且听风吟,静待花开。也符合我对技术的看法,想要真正掌握一门技术就需要厚积薄发的毅力,同时保持乐观的心态。

你只管努力,剩下的交给时间!

文章目录

  • 一、前言
  • 二、索引操作
    • 2.1、创建索引
    • 2.2、删除索引
    • 2.3、修改索引副本数
  • 三、基础增删改查
    • 3.1、插入数据
    • 3.2、删除数据
    • 3.3、更新数据
    • 3.4、基础查询数据
      • 3.4.1、搜索全部数据(默认展示10条数据)
      • 3.4.2、指定文档id搜索数据:
      • 3.4.3、根据关键字搜索数据
      • 3.4.4、高亮显示数据
  • 四、DSL查询
  • 五、聚合查询
  • 六、批量操作
  • 七、实用骚操作
    • 7.1、浏览器查询结果美化
    • 7.2、指定返回的字段
    • 7.3、不显示元数据
    • 7.4、查看文档是否存在
    • 7.5、分页查询
  • 八、总结

一、前言

本文版本说明:

  1. ElasticSearch版本:7.7 (目前最新版)
  2. Kibana版本:7.7(目前最新版)

前面两篇文章咱们已经对Elasticsearch进行了精细的讲解,第一篇围绕Elasticsearch最新版进行了上万字的详细解析,相信看过的朋友对Elasticsearch及kibana等工具的极速安装配置印象深刻,也至少会对Elasticsearch有一个入门的掌握。第二篇主要围绕Elasticsearch的分词器进行讲解,并重点分析了ik中文分词器。

前文链接

  1. ElasticSearch最新版快速入门详解
  2. ElasticSearch中文分词,看这一篇就够了

本文咱们将对Elasticsearch原生的RESTful API操作进行详尽的归纳分析,并会对复杂的常用查询知识点进行一一举例展开,重点会对DSL查询,聚合查询,批量操作等进行举例解析,并会提供一些Elasticsearch的使用技巧。相信学会了这些知识和技巧之后,以后在工作中不管应对多么复杂的场景,都可以得心应手,迅速的根据RESTful API写出完美的代码。好了,废话不多说,让我们开始吧!

注意:下文咱们把ElasticSearch简称为ES,对大家可能出现的疑问进行标红并解释,并会对容易混淆的地方加以声明。

二、索引操作

2.1、创建索引

比如咱们创建一个3副本2分片的名为ropledata的索引:

PUT /ropledata
{"settings": { "number_of_shards": "2", "number_of_replicas": "3"}
}

2.2、删除索引

和删除数据库一样,索引也是可以删除的,只需要执行如下命令就可以删除名为ropledata的索引:

DELETE /ropledata

2.3、修改索引副本数

这里要注意,索引的分片不允许修改的,咱们只能修改索引的副本数量,比如想把副本数量修改为2个,只需要执行:

PUT ropledata/_settings
{ "number_of_replicas" : "2"
}

三、基础增删改查

3.1、插入数据

咱们平时进行基础的数据插入时,可以分为两种情况。一种是指定文档的id,一种是不指定。

注意:不指定的时候,ES会帮我们自动生成,不过不容易记忆,因此推荐指定id的方式插入数据。

疑问一:这里说的id是大括号里面的id吗?

不是的,这点容易混淆,这里包括后面查询或者删除时候用到的ID是创建文档时候指定或者ES自动生成的那个id,那个是唯一id,也就是下面示例里的101,而不是文档里面大括号的那个叫id 字段!文档里面的文档字段是可以没有id 的。

  1. 不指定id

    POST /ropledata/_doc/
    {"id":1,"name":"且听_风吟","page":"https://ropledata.blog.csdn.net","say":"欢迎点赞,收藏,关注,一起学习"
    }
    
  2. 指定id

    POST /ropledata/_doc/101
    {"id":1,"name":"且听_风吟","page":"https://ropledata.blog.csdn.net","say":"欢迎点赞,收藏,关注,一起学习"
    }
    

3.2、删除数据

如果咱们想删除刚才创建的ropledata索引下的id为101的文档,可以使用如下命令:

DELETE /ropledata/_doc/101

3.3、更新数据

这里大家要特别注意,ES里的文档是不可以修改的,但是可以覆盖,所以ES修改数据本质上是对文档的覆盖。

ES对数据的修改分为全局更新局部更新,下面咱们进行对比说明:

  1. 全局更新

    PUT /ropledata/_doc/101
    { "id":1,"name":"且听_风吟","page":"https://ropledata.blog.csdn.net","say":"再次欢迎点赞,收藏,关注,一起学习"
    }
    

    然后大家可以多全局更新几次,会发现每次全局更新之后这个文档的_version都会发生改变!

  2. 局部更新

    POST /ropledata/_update/101
    {"doc":{"say":"奥力给"}
    }
    

    这时候我们可以多次去执行上面的局部更新代码,会发现除了第一次执行,后续不管又执行了多少次,_version都不再变化!

    疑问二:局部更新的时候ES底层的流程是怎样的?和全局更新相比性能怎么样?

    局部更新的底层流程:

    1. 内部先获取到对应的文档;
    2. 将传递过来的字段更新到文档的json中(这一步实质上也是一样的);
    3. 将老的文档标记为deleted(到一定时候才会物理删除);
    4. 将修改后的新的文档创建出来。

    性能对比:

    1. 全局更新本质上是替换操作,即使内容一样也会去替换;
    2. 局部更新本质上是更新操作,只有遇到新的东西才更新,没有新的修改就不更新;
    3. 局部更新比全局更新的性能好,因此推荐使用局部更新。

3.4、基础查询数据

3.4.1、搜索全部数据(默认展示10条数据)
  1. GET全局搜索数据:

    GET /ropledata/_search
    
  2. match_all全局搜索数据,可以加各种条件,比如排序:

    POST /ropledata/_search
    {"query": {"match_all": {}},"sort": [{"id": {"order": "asc"}}]
    }
    

    以match_all为例,查询后的结果如下:

    疑问三:查询出来的字段都是什么含义呢?

    1. took:Elasticsearch运行查询需要多长时间(以毫秒为单位);
    2. timed_out :搜索请求是否超时 ;
    3. _shards 搜索了多少碎片,并对多少碎片成功、失败或跳过进行了细分;
    4. _max_score 找到最相关的文档的得分;
    5. hits.total.value :找到了多少匹配的文档;
    6. hits.sort :文档排序后的位置(比如上面查询的1,2,3…) ;
    7. hits._score:文档的相关性评分(在使用match_all时不适用)
3.4.2、指定文档id搜索数据:
GET /ropledata/_doc/101
3.4.3、根据关键字搜索数据

比如咱们想查找ropledata这个索引下,name字段为**“且听风吟,静待花开”**的数据:

GET /ropledata/_search?q=name:"且听风吟,静待花开"
3.4.4、高亮显示数据

注意:使用高亮查询,会对要查询的数据进行分词搜索!

有时候我们想把查询到的数据进行高亮显示,比如查到“且听风吟”后,想把name这个字段的数据高亮显示,可以用如下的方式:

POST /ropledata/_search
{"query": {"match": {"name": "且听风吟"}},"highlight": {"fields": {"name": {}}}
}

查询后,可以得到如下结果:

我们可以发现,会查询到分词后的“且听风吟”,同时会把name个字段分词后的数据进行高亮强调显示。注:这里的"<em></em>"标签在html里有强调文本的作用,支持所有的浏览器!

四、DSL查询

疑问四:DSL是啥意思呢?怎么通俗点解释呢?

简单来说,DSL就是ES的一种查询方式,DSL基于JSON实现了直观简单的结构化查询功能。由于DSL查询是JSON格式的,所以更加的灵活,而且可以同时包含查询和过滤器,咱们可以很轻松的构造出复杂的查询功能。

好,废话不多说,咱们把常用的关键点逐一展开,最后再来个复杂的查询玩玩:

  1. term查询

    term需要完全匹配,不会对词汇进行分词器分析。主要用于查询精确匹配的值,比如数字,日期,布尔值或未经分析的文本数据类型的字符串 (not_analyzed)。

    比如咱们查询id字段为9的数据(注意:这里的id不是文档id,是文档里的咱们自己命名为id的字段):

    POST /ropledata/_search
    {"query": {"term": {"id": 9}}
    }
    
  2. terms查询

    terms和term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配。

    比如咱们查询id字段为9和5的数据:

    POST /ropledata/_search
    {"query": {"terms": {"id": [5,9]}}
    }
    
  3. range查询

    range 主要用于过滤,通常用于按照指定范围查找一批数据,咱们需要记忆如下四个关键字的含义:

    1. gt :大于
    2. gte : 大于等于
    3. lt :小于
    4. lte : 小于等于

    记忆小技巧:gt可以理解为高to,也就是高于,大于的意思。lt可以理解为little to,也就是小于的意思。然后加上e就附加一个等于。

    比如咱们想要查询id字段大于等于5且小于10的数据:

    POST /ropledata/_search
    {"query": {"range": {"id": {"gte": 5,"lt": 10}}}
    }
    
  4. exists查询

    exists查询类似sql里的is null条件,通常用于查找文档中是否包含指定字段,包含这个字段就返回返回这条数据。

    比如咱们想查询ropledata这个索引下,包含hobby这个字段的数据:

    POST /ropledata/_search
    {"query": {"exists": {"field": "hobby"}}
    }
    
  5. match查询

    match 查询是一个标准查询,不管是全文本查询还是精确查询基本上都要用到它。所以非常非常重要,一定要掌握。

    在使用 match 查询一个全文本字段时,它会在真正查询之前用分析器先分析match一下查询字符;如果用 match 下指定了一个确切值, 在遇到数字,日期,布尔值或者 not_analyzed 的字符串时,它将为你搜索你给定的值。

    比如咱们查询hobbyrun的数据:

    POST /ropledata/_search
    {"query": {"match": {"hobby": "run"}}
    }
    
  6. match_phrase查询

    疑问五:match_phrase和match有啥区别呢?

    match_phrase和match类似,在查询时都会对查询词进行分词,但是match会忽略查询词的空格,而match_phrase不会。因此需要注意的是:查询包含空格的字符串,要用match_phrase!

    比如咱们查询hobbymusic and movie的数据(注意:这里要查询的数据包含空格):

    POST /ropledata/_search
    {"query": {"match_phrase": {"hobby": "music and movie"}}
    }
    
  7. bool查询

    bool 查询可以用来合并多个条件查询结果的布尔逻辑,咱们需要记忆如下操作符关键字:

    1. must:多个查询条件的完全匹配,相当 于 and;
    2. must_not:多个查询条件的相反匹配,相当于 not;
    3. should:至少有一个查询条件匹配, 相当于 or。

    注意:这些参数可以分别继承一个查询条件或者一个查询条件的数组。

    比如咱们想查询hobby必须是runid必须不是4name可以是一起学习或者且听风吟的数据:

    POST /ropledata/_search
    {"query": {"bool": {"must": {"term": {"hobby": "run"}},"must_not": {"term": {"id": 4}},"should": [{"term": {"name": "且听风吟"}},{"term": {"name": "一起学习"}}]}}
    
  8. filter查询

    filter用于过滤查询,通常和bool连用,就像编程语言一样,用于过滤数据。

    比如咱们想查询hobbymusic的用户:

    POST /ropledata/_search
    {"query": {"bool": {"filter": {"term": {"hobby": "music"}}}}
    }
    
  9. 融合在一起使用

    其实常用的就是上面这些,它们一般是融合在一起使用的。比如咱们要查询id必须不是4name包含且听风吟,同时id大于等于2且小于10的数据:

    POST /ropledata/_search
    {"query": {"bool": {"filter": {"range": {"id": {"gte": 2,"lt": 10}}},"must_not": {"term": {"id": 4}},"must": {"match": {"name": "且听风吟"}}}}
    }
    

五、聚合查询

学会了非常实用的DSL查询,下面咱们再看看聚合查询。

  1. 常用数学统计函数

    首先咱们需要了解几个非常常用的数学统计函数:

    1. avg:平均值
    2. max:最大值
    3. min:最小值
    4. sum:求和

    比如咱们求id的平均值,有两种写法,基础写法和脚本写法:

    基础写法:

    POST /ropledata/_search
    {"aggs": {"ropledata": {"avg": {"field": "id"}}},"size": 0
    }
    

    脚本写法:

    POST /ropledata/_search
    {"aggs": {"ropledata": {"avg": {"script": {"source": "doc.id.value"}}}},"size": 0
    }
    

    疑问六:求平均值或求和时,为什么要加(“size”: 0)呢?

    size用来控制返回多少数据,由于咱们是想要在所有文档里求平均值和求和,所以要用size来控制返回一个数据即可,不然ES还会默认返回10条数据。

  2. cardinality去查

    涉及到聚合查询的场景,当然少不了去重了,ES提供了cardinality去重统计函数来解决这个问题。

    比如咱们想根据id字段去重统计:

    POST /ropledata/_search
    {"aggs": {"ropledata": {"cardinality": {"field": "id"}}},"size": 0
    }
    
  3. value_count计数统计

    有时候咱们会遇到让统计个数的场景,这时候就可以使用value_count来解决了。

    比如咱们要统计有多少条数据:

    POST /ropledata/_search
    {"aggs": {"ropledata": {"value_count": {"field": "id"}}},"size": 0
    }
    
  4. terms词聚合

    terms词聚合可以基于给定的字段,并按照这个字段对应的每一个数据为一个桶,然后计算每个桶里的文档个数。默认会按照文档的个数排序。

    比如咱们要根据id字段进行词聚合:

    POST /ropledata/_search
    {"aggs": {"ropledata": {"terms": {"field": "id"}}}
    }
    
  5. top_hits聚合

    咱们使用sql时可以很方便的处理top问题,ES也提供了对应的支持,top_hits就是这样的函数,一般和terms连用,可以获取到每组前n条数据。

    比如咱们想根据id分组,然后拿到前6条数据:

    POST /ropledata/_search
    {"aggs": {"ropledata": {"terms": {"field": "id"},"aggs": {"count": {"top_hits": {"size": 6}}}}},"size": 0
    }
    
  6. range范围查询

    在咱们日常进行数据统计时,控制数据的范围是必不可少的,除了前面DSL查询时介绍的gt,lt函数,其实在聚合查询里还提供了range用来进行范围查询。

    比如咱们想查询id字段的值在6-9之间和10-20之间的文档有多少:

    POST /ropledata/_search
    {"aggs": {"group_by_id": {"range": {"field": "id","ranges": [{"from": 6,"to": 9},{"from": 10,"to": 20}]}}},"size": 0
    }
    

六、批量操作

作为一个存储系统,对数据的批量增删改查自然也是必不可少的!ES也提供了批量的操作,具体的用法如下。

  1. 批量插入

    POST _bulk
    { "create" : { "_index" : "ropledata", "_id" : "1009" } }
    {"id":9,"name": "且听风吟,静待花开","hobby": "music and movie"}
    { "create" : { "_index" : "ropledata", "_id" : "1010" } }
    {"id":10,"name": "且听_风吟","hobby": "music"}
    { "create" : { "_index" : "ropledata", "_id" : "1011" } }
    {"id":11,"name": "大数据领域","hobby": "movie"}
    { "create" : { "_index" : "ropledata", "_id" : "1012" } }
    {"id":12,"name": "一起学习","hobby": "run"}
    
  2. 批量查询

    比如咱们想批量查询ropledata这个索引下文档id为1010,1011,1012的文档数据,可以这样写:

    POST /ropledata/_mget
    {"ids": ["1010","1011","1012"]
    }
    
  3. 批量更新

    如果咱们想批量修改1011和1012的文档里的name字段的值,可以这样写:

    POST _bulk
    { "update" : {"_id" : "1011", "_index" : "ropledata"} } { "doc" : {"name" : "批量修改"} }
    { "update" : {"_id" : "1012", "_index" : "ropledata"} } { "doc" : {"name" : "大家好"}}
    
  4. 批量删除

    如果咱们想批量删除文档id为1011和1012的文档,可以这样写:

    POST _bulk
    { "delete" : { "_index" : "ropledata", "_id" : "1011" } }
    { "delete" : { "_index" : "ropledata", "_id" : "1012" } }
    

七、实用骚操作

7.1、浏览器查询结果美化

咱们之前介绍的所有的操作,都是在kibana里输入的,里面可以对输入的命令和输出的结果进行格式化。但是如果咱们直接使用浏览器进行查询时,输出的查询结果会乱成一团,那么怎么去美化呢?

别急,只要在查询的最后加上pretty参数,就可以了:

http://127.0.0.1:9200/ropledata/_doc/1001?pretty

查询出来的结果就会被美化了:

7.2、指定返回的字段

咱们有时候不需要返回整个文档所有的字段,只想要查看其中的一个或者多个字段,这时候ES也提供的有方法,只需要在最后使用**_source**参数,并传递想要返回的字段就可以了。

http://127.0.0.1:9200/ropledata/_doc/1001?pretty&_source=id,name

7.3、不显示元数据

咱们查询的时候,会返回一大堆数据,上面那些称为元数据,那不需要的时候,怎么去掉呢?别急,只需要把_doc换成_source就可以了。

http://127.0.0.1:9200/ropledata/_source/1001?pretty&_source=id,name

7.4、查看文档是否存在

有时候咱们为了防止报错,在查询之前,需要查看这个文档是否存在,这时候只需要用到HEAD关键字就可以了。

HEAD /ropledata/_doc/1001

7.5、分页查询

对于海量存储的数据,有时候咱们需要分页查看。ES提供了sizefrom两个参数,size代表每页的个数,默认是10个,from代表从第几个获取。咱们只要在代码里写清楚这两个参数,就可以实现翻译了。

http://127.0.0.1:9200/ropledata/_search?size=1&from=2&pretty

八、总结

本文围绕ES最新版本,从常用基础操作、DSL查询、聚合查询、批量操作,实用技巧等方面进行了详细的举例解析,并对读者可能出现的疑惑进行了标红疑问总结(本文共总结了六处容易产生的疑问点),对需要注意的地方也进行了单独的声明,希望对大家学习ES提供帮助!

注意:如果我的文章对您有所帮助,欢迎关注点赞收藏,如果您有疑惑或发现文中有不对的地方,还请不吝赐教,非常感谢!!

最清晰易懂的Elasticsearch操作手册|收藏夹必备相关推荐

  1. 微信小程序之实现层叠轮播图的效果案例(前端学习收藏夹必备)

    效果展示 代码展示: WXML代码 <view class="selection_cards" bindtouchstart="touchstart" b ...

  2. 哪些知乎收藏夹关注数超过一万?

    我们先看榜单共计432个收藏夹关注数超过一万,看完榜单之后看抓取思路. 以下格式按照(关注人数,收藏夹链接),从高到低降序排序. 102884 知乎经典问题 - 收藏夹 76771 醍醐灌顶 - 收藏 ...

  3. 将favdb转换成html,360浏览器收藏夹使用小记

    360浏览器(下称浏览器)有本地收藏夹还有网络收藏夹,在没有登录之前使用的是本地收藏夹,登录以后使用的是网络收藏夹. 不管登录前还是登录后,均有整理收藏夹及导入导出的功能 1.整理收藏夹 就是对收藏的 ...

  4. 专业流程拓扑软件IAuto3.1.1用户操作手册——赶紧收藏,功能比processon、visio、draw.io更强大!小巧易用!

    专业流程拓扑软件IAuto3.1.1用户操作手册--赶紧收藏 IAuto流程软件是一款国产专业的集[画流程拓扑图](业务流程图.思维导图.组织结构图.网络拓扑图.架构图.甘特图.时序图.信息图.鱼骨图 ...

  5. 编写用户帮助/操作手册指南

    背景: 用户操作手册是一份指导用户使用产品或服务的重要手册. 一个新系统,需要写用户操作手册,该从何下笔?本篇是一篇教你编写用户帮助/操作手册的指南- 首先,先来看一个反例 : 这个是我入职的时候,我 ...

  6. 操作手册的目的、传统的产品操作手册弊端、如何设计优质手册

    操作手册是详细描述软件的功能.性能和用户界面,使用户了解到如何使用该软件的说明书.很多时候,当我们对产品的某个功能感到困惑时,往往需要一份操作手册来帮助我们解答疑惑. 何为操作手册,官方的定义如下:操 ...

  7. 绝对详细的 RabbitMQ 实践操作手册(一)

    绝对详细的 RabbitMQ 实践操作手册,看完本系列就够了. 一.什么是MQ ? 1.MQ的概念 2.理解消息队列 二.MQ的优势和劣势 1.优势和作用 2.劣势 三.MQ的应用场景 四.AMQP ...

  8. 最好的程序界面就是用户无需去阅读操作手册就知道该如何使用的界面

    最好的程序界面就是用户无需去阅读操作手册就知道该如何使用的界面. 原则 1.一致性  如果你可以在一个列表的项目上双击后能 够弹出对话框,那么应该在任何列表中双击都能弹出对话框.要有统一的字体写号.统 ...

  9. 工具类软件操作手册_全套广联达软件学习资料合集:教程+实例讲解+操作手册,一文搞定...

    要学习并掌握好算量软件,不仅仅需要软件知识,还需要各种造价相关知识,只有精通软件及造价知识,才能大大的提高算量的速度及准确度. 一个算量的高手掌握的不单是软件操作技术,还要掌握的是造价的基础知识,你要 ...

最新文章

  1. JAVA增删改查XML文件
  2. 基于光流的3D速度检测
  3. [MySQL 5.6] GTID实现、运维变化及存在的bug
  4. RedHat YUM configure
  5. mysqldatadir 转移
  6. Vue的钩子函数是什么意思?Vue都有哪些钩子函数?
  7. ztree在onCheck()方法中防止因触发联动关系导致页面多次渲染而卡死的问题
  8. (python)7-4 sdut-oop-1 简单的复数运算 (10 分)
  9. 正反斜杠的区别_电脑中的正斜杠(/)与反斜杠(\)的区别
  10. Zabbix 结合 bat 脚本与计划任务开启 windows 远程桌面
  11. 【渝粤教育】国家开放大学2018年春季 0267-21T摄影技术 参考试题
  12. idea格式化代码快捷键
  13. 2.ActiveMQ下载和安装(Linux版)
  14. GRMS_README
  15. About Redistribute
  16. 生死狙击为什么无法显示服务器,生死狙击外国服务器越南服注册
  17. ora-20000:ORU-10027: buffer overflow
  18. html转盘游戏代码,html5 canvas大转盘抽奖提示代码
  19. Python+selenium自动化之26----等待
  20. Intellij IDEA常用快捷键一览(windows)

热门文章

  1. docker 安装mysql8.0并且暴漏外部的连接
  2. pyqt5使用pyinstaller打包项目为exe
  3. 谷歌刷新纪录:将圆周率精确到了小数点后31万亿位,光存储就占了几个大硬盘!
  4. 多因子系列(二):基于机器学习选股策略(附源码)
  5. openlayers3 ol3热力图 json
  6. NeuS: Learning Neural Implicit Surfaces by Volume Rendering for Multi-view Reconstruction
  7. Debian10安装教程
  8. ie网站无法找到服务器,IE中无法找到已经安装的个人证书
  9. [ECCV2018]Generating 3D faces using Convolutional Mesh Autoencoders
  10. 道与术 渠道以及通信方式的架构设计