Elasticsearch|ElasticSearch 之初步上手


文章目录

    • 1. Elasticsearch 产生背景
    • 2. Elasticsearch 介绍
      • 2.1 Lucene与Elasticsearch关系
      • 2.2 Elasticsearch核心概念
      • 2.3 与关系型数据库Mysql对比
      • 2.4 ES逻辑设计(文档-->类型-->索引)
      • 2.5 ES物理设计
      • 2.6 ELK是什么
      • 2.7 Elasticsearch特点和优势
      • 2.8 Elasticsearch 业务场景
      • 2.9 Elasticsearch 索引到底能处理多大数据
    • 3. ElasticSearch 安装
      • 3.1 安装 ElasticSearch
      • 3.2 关闭 es
    • 4. Elasticsearch 插件介绍
      • 4.1 核心插件
      • 4.2 第三方插件
      • 4.3 插件安装
    • 5. ElasticSearch 之 ElasticSearch-head
      • 5.1 安装 Node.js
      • 5.2 安装 Grunt
      • 5.3 下载 Head
      • 5.4 配置跨域
    • 6. ElasticSearch 安装 Kibana
      • 6.1 Kibana 介绍
      • 6.2 下载 Kibana
      • 6.3 修改配置文件
      • 6.4 启动
      • 6.5 查看
    • 7. Elasticsearch 之 索引操作
      • 7.1 索引初始化
      • 7.2 更新索引
      • 7.3 删除索引
    • 8. Elasticsearch 之 映射管理
      • 8.1 映射介绍
      • 8.2 字段数据类型
      • 8.3 映射参数
      • 8.4 创建索引
      • 8.5 查看索引
    • 9. Elasticsearch 的增删查改(CURD)
      • 9.1 CURD 之 Create
      • 9.2 CURD 之 Update
      • 9.3 CURD 之 Delete
      • 9.4 CURD 之 Retrieve
    • 10. Elasticsearch 之查询的两种方式
      • 10.1 查询字符串
      • 10.2 结构化查询
    • 11 term 与 match 查询
      • 11.1 match 系列之 match(按条件查询)
      • 11.2 match 系列之 match_all(查询全部)
      • 11.2 match 系列之 match_phrase(短语查询)
      • 11.3 match 系列之 match_phrase_prefix(最左前缀查询)

1. Elasticsearch 产生背景 1.1 大规模数据如何检索
如:当系统数据量上了10亿、100亿条的时候,在做系统架构的时候通常会从以下角度去考虑问题:
1)用什么数据库好?(mysql、oracle、mongodb、hbase…)
2)如何解决单点故障;(lvs、F5、A10、Zookeeper、MQ)
3)如何保证数据安全性;(热备、冷备、异地多活)
4)如何解决检索难题;(数据库代理中间件:mysql-proxy、Cobar、MaxScale等; )
5)如何解决统计分析问题;(离线、近实时)
1.2 传统数据库的应对解决方案
对于关系型数据,我们通常采用以下或类似架构去解决查询瓶颈和写入瓶颈:
解决要点:
1)通过主从备份解决数据安全性问题;
2)通过数据库代理中间件心跳监测,解决单点故障问题;
3)通过代理中间件将查询语句分发到各个slave节点进行查询,并汇总结果
1.3 非关系型数据库解决方案
对于Nosql数据库,以mongodb为例,其它原理类似:
解决要点:
1)通过副本备份保证数据安全性;
2)通过节点竞选机制解决单点问题;
3)先从配置库检索分片信息,然后将请求分发到各个节点,最后由路由节点合并汇总结果
1.4 内存数据库解决方案
完全把数据放在内存中是不可靠的,实际上也不太现实,当我们的数据达到PB级别时,按照每个节点96G内存计算,在内存完全装满的数据情况下,需要的机器是:1PB=1024T=1048576G
节点数=1048576/96=10922个
实际上,考虑到数据备份,节点数往往在2.5万台左右。成本巨大决定了其不现实!
所以把数据放在内存也好,不放在内存也好,都不能完完全全解决问题。
全部放在内存速度问题是解决了,但成本问题上来了。
为解决以上问题,从源头着手分析,通常会从以下方式来寻找方法:
1、存储数据时按有序存储;
2、将数据和索引分离;
3、压缩数据;
这就引出了 Elasticsearch
2. Elasticsearch 介绍 Elasticsearch 是一个基于Lucene的分布式搜索和分析引擎。
ES是elaticsearch简写, Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
Elasticsearch使用Java开发,在Apache许可条款下开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便
使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,使得全文检索变得简单
设计用途:用于分布式全文检索,通过HTTP使用JSON进行数据索引,速度快
2.1 Lucene与Elasticsearch关系
1)Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。
2)Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
2.2 Elasticsearch核心概念
Cluster:集群
ES可以作为一个独立的单个搜索服务器。不过,为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。
Node:节点
形成集群的每个服务器称为节点。
Shard:分片
当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。
当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。
Replia:副本
为提高查询吞吐量或实现高可用性,可以使用分片副本。
副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片。
当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。
全文检索
全文检索就是对一篇文章进行索引,可以根据关键字搜索,类似于mysql里的like语句。
全文索引就是把内容根据词的意义进行分词,然后分别创建索引,例如”今日是周日我们出去玩” 可能会被分词成:“今天“,”周日“,“我们“,”出去玩“ 等token,这样当你搜索“周日” 或者 “出去玩” 都会把这句搜出来。
2.3 与关系型数据库Mysql对比
Elasticsearch|ElasticSearch 之初步上手
文章图片

  1. 关系型数据库中的数据库(DataBase),等价于ES中的索引(Index)
  2. 一个数据库下面有N张表(Table),等价于1个索引Index下面有N多类型(Type),
  3. 一个数据库表(Table)下的数据由多行(ROW)多列(column,属性)组成,等价于1个Type由多个文档(Document)和多Field组成。
  4. 在一个关系型数据库里面,schema定义了表、每个表的字段,还有表和字段之间的关系。 与之对应的,在ES中:Mapping定义索引下的Type的字段处理规则,即索引如何建立、索引类型、是否保存原始索引JSON文档、是否压缩原始JSON文档、是否需要分词处理、如何进行分词处理等。
  5. 在数据库中的增insert、删delete、改update、查search操作等价于ES中的增PUT/POST、删Delete、改_update、查GET.1.7
2.4 ES逻辑设计(文档–>类型–>索引)
一个索引类型中,包含多个文档,比如说文档1,文档2。
当我们索引一篇文档时,可以通过这样的顺序找到它:索引 ? 类型 ?文档ID,通过这个组合我们就能索引到某个具体的文档。
注意:ID不必是整数,实际上它是个字符串。
文档
之前说elasticsearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,elasticsearch中,文档有几个重要属性:
  • 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含key:value
  • 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的
  • 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用,在elasticsearch中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个新的字段。
  • 文档是无模式的,也就是说,字段对应值的类型可以是不限类型的。
尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类型,可以是字符串也可以是整型。因为elasticsearch会保存字段和类型之间的映射及其他的设置。这种映射具体到每个映射的每种类型(详见扩展阅读:17-扩展阅读-删除映射类型.md),这也是为什么在elasticsearch中,类型有时候也称为映射类型。
类型
1、类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。
2、类型中对于字段的定义称为映射,比如name映射为字符串类型。
3、我们说文档是无模式的,它们不需要拥有映射中所定义的所有字段,比如新增一个字段,是怎么做的呢?elasticsearch会自动的将新字段加入映射,但是这个字段的不确定它是什么类型,elasticsearch就开始猜,如果这个值是18,那么elasticsearch会认为它是整型。
4、但是elasticsearch也可能猜不对,所以最安全的方式就是提前定义好所需要的映射,这点跟关系型数据库殊途同归了,先定义好字段,然后再使用,别整什么幺蛾子。后面在讨论更多关于映射的东西。
索引
索引是映射类型的容器,elasticsearch中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置。然后它们被存储到了各个分片上了。
2.5 ES物理设计
一个集群包含至少一个节点,而一个节点就是一个elasticsearch进程。节点内可以有多个索引。 默认的,如果你创建一个索引,那么这个索引将会有5个分片(primary shard,又称主分片)构成,而每个分片又有一个副本(replica shard,又称复制分片),这样,就有了10个分片。 那么这个索引是如何存储在集群中的呢? 图中有3个节点的集群,可以看到主分片和对应的复制分片都不会在同一个节点内,这样有利于某个节点挂掉了,数据也不至于丢失。 实际上,一个分片是一个Lucene索引,一个包含倒排索引的文件目录,倒排索引的结构使得elasticsearch在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字

Elasticsearch|ElasticSearch 之初步上手
文章图片

2.6 ELK是什么
ELK=elasticsearch+Logstash+kibana
elasticsearch:后台分布式存储以及全文检索
logstash: 日志加工、“搬运工”
kibana:数据可视化展示。
ELK架构为数据分布式存储、可视化查询和日志解析创建了一个功能强大的管理链。 三者相互配合,取长补短,共同完成分布式大数据处理工作。
2.7 Elasticsearch特点和优势
1)分布式实时文件存储,可将每一个字段存入索引,使其可以被检索到。
2)实时分析的分布式搜索引擎。
分布式:索引分拆成多个分片,每个分片可有零个或多个副本。集群中的每个数据节点都可承载一个或多个分片,并且协调和处理各种操作;
负载再平衡和路由在大多数情况下自动完成。
3)可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。也可以运行在单台PC上(已测试)
4)支持插件机制,分词插件、同步插件、Hadoop插件、可视化插件等。
2.8 Elasticsearch 业务场景
实际项目开发实战中,几乎每个系统都会有一个搜索的功能,当搜索做到一定程度时,维护和扩展起来难度就会慢慢变大,所以很多公司都会把搜索单独独立出一个模块,用ElasticSearch等来实现。
近年ElasticSearch发展迅猛,已经超越了其最初的纯搜索引擎的角色,现在已经增加了数据聚合分析(aggregation)和可视化的特性,如果你有数百万的文档需要通过关键词进行定位时,ElasticSearch肯定是最佳选择。当然,如果你的文档是JSON的,你也可以把ElasticSearch当作一种“NoSQL数据库”, 应用ElasticSearch数据聚合分析(aggregation)的特性,针对数据进行多维度的分析。
尝试使用ES来替代传统的NoSQL,它的横向扩展机制太方便了
应用场景:
1)新系统开发尝试使用ES作为存储和检索服务器; 2)现有系统升级需要支持全文检索服务,需要使用ES

2.9 Elasticsearch 索引到底能处理多大数据
单一索引的极限取决于存储索引的硬件、索引的设计、如何处理数据以及你为索引备份了多少副本。
通常来说,一个Lucene索引(也就是一个elasticsearch分片,一个es索引默认5个分片)不能处理多于21亿篇文档,或者多于2740亿的唯一词条。但达到这个极限之前,我们可能就没有足够的磁盘空间了!
当然,一个分片如何很大的话,读写性能将会变得非常差
3. ElasticSearch 安装 3.1 安装 ElasticSearch
一、 安装JDK环境
因为ElasticSearch是用Java语言编写的,所以必须安装JDK的环境,并且是JDK 1.8以上
官方网址:https://www.oracle.com/java/technologies/downloads/
安装完成查看java版本
java -version

Elasticsearch|ElasticSearch 之初步上手
文章图片

二、 官网下载elasticsearch
官方网站:https://www.elastic.co/cn/downloads/elasticsearch
Elasticsearch|ElasticSearch 之初步上手
文章图片

Elasticsearch|ElasticSearch 之初步上手
文章图片

Elasticsearch|ElasticSearch 之初步上手
文章图片

三、 启动 es
1. 下载完成后解压并在cmd中切换到bin路径下 cd elasticsearch-/bin2. 启动es,在 cmd 中输入 elasticsearch 启动。如果是在 Windows 上面运行 Elasticseach,应该 运行 bin/elasticsearch.bat 而不是 bin/elasticsearch

启动完可以测试,如下所示:
在浏览器输入以下地址:http://127.0.0.1:9200/,可以看到以下内容
Elasticsearch|ElasticSearch 之初步上手
文章图片

如果在运行中出现如下异常
Elasticsearch|ElasticSearch 之初步上手
文章图片

只需要将 elasticsearch-7.5.0\config\elasticsearch.keystore.tmp 文件删除即可
3.2 关闭 es
# 查看进程 ps -ef | grep elastic# 干掉进程 kill -9 2382(进程号)# 以守护进程方式启动es elasticsearch -d

4. Elasticsearch 插件介绍 es插件是一种增强Elasticsearch核心功能的途径。它们可以为es添加自定义映射类型、自定义分词器、原生脚本、自伸缩等等扩展功能。
es插件包含JAR文件,也可能包含脚本和配置文件,并且必须在集群中的每个节点上安装。安装之后,需要重启集群中的每个节点才能使插件生效。
es插件包含核心插件和第三方插件两种
4.1 核心插件
核心插件是elasticsearch项目提供的官方插件,都是开源项目。这些插件会跟着elasticsearch版本升级进行升级,总能匹配到对应版本的elasticsearch,这些插件是有官方团队和社区成员共同开发的。
官方插件地址: https://github.com/elastic/elasticsearch/tree/master/plugins
4.2 第三方插件
第三方插件是有开发者或者第三方组织自主开发便于扩展elasticsearch功能,它们拥有自己的许可协议,在使用它们之前需要清除插件的使用协议,不一定随着elasticsearch版本升级, 所以使用者自行辨别插件和es的兼容性。
4.3 插件安装
elasticsearch的插件安装方式还是很方便易用的。
它包含了命令行,url,离线安装三种方式。
核心插件随便选择一种方式安装均可,第三方插件建议使用离线安装方式
第一种:命令行
bin/elasticsearch-plugin install [plugin_name] # bin/elasticsearch-plugin install analysis-smartcn安装中文分词器

第二种:url安装
bin/elasticsearch-plugin install [url] # bin/elasticsearch-plugin install https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-smartcn/analysis-smartcn-6.4.0.zip

第三种:离线安装
#https://artifacts.elastic.co/downloads/elasticsearch-plugins/analysis-smartcn/analysis-smartcn-6.4.0.zip # 点击下载analysis-smartcn离线包 # 将离线包解压到ElasticSearch 安装目录下的 plugins 目录下 # 重启es。新装插件必须要重启es

注意:插件的版本要与 ElasticSearch 版本要一致
5. ElasticSearch 之 ElasticSearch-head elasticsearch-head 是 elasticsearch 的一款可视化工具,依赖于 node.js ,所以需要先安装 node.js
5.1 安装 Node.js

5.2 安装 Grunt
# Grunt是基于Node.js的项目构建工具。它可以自动运行你所设定的任务 npm install grunt -g

5.3 下载 Head
官网:https://github.com/mobz/elasticsearch-head
# 解压后切换到目录下 cd elasticsearch-head# 通过npm安装依赖 npm install# 启动 npm run start# 在浏览器里打开,界面如下所示 http://localhost:9100/

Elasticsearch|ElasticSearch 之初步上手
文章图片

5.4 配置跨域
修改 Elasticsearch 安装目录中 config 文件夹下 elasticsearch.yml 文件,加入下面两行:
添加配置时,:后必须空格,不然启动闪退
http.cors.enabled: true http.cors.allow-origin: "*"

启动 Elasticsearch ,如下页面即为成功
Elasticsearch|ElasticSearch 之初步上手
文章图片

6. ElasticSearch 安装 Kibana 6.1 Kibana 介绍
Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,设计用于和 Elasticsearch 协作。
您、可以使用 Kibana 对 Elasticsearch 索引中的数据进行搜索、查看、交互操作。
可以很方便的利用图表、表格及地图对数据进行多元化的分析和呈现
详情可见用户手册:
https://www.elastic.co/guide/cn/kibana/current/index.html
注意跟Elasticsearch版本兼容情况,详情见:
https://www.elastic.co/cn/support/matrix#matrix_compatibility
下载地址为:
https://www.elastic.co/cn/downloads/past-releases
6.2 下载 Kibana
到相应地址,下载即可,解压下载后的文件
Elasticsearch|ElasticSearch 之初步上手
文章图片

6.3 修改配置文件
修改配置文件:vim 安装目录 /config/kibana.yml
# 更多配置信息,详见 https://www.elastic.co/guide/cn/kibana/current/settings.html server.port: 5601 server.host: "127.0.0.1" server.name: lqz elasticsearch.hosts: ["http://localhost:9200/"]

6.4 启动
到安装目录下:
./bin/kibana # 正常启动

6.5 查看
在浏览器里访问:http://localhost:5601/app/kibana
(如访问不到,尝试删除es中跟kibana相关的索引)
选择 Dev Tools
Elasticsearch|ElasticSearch 之初步上手
文章图片

在 console 中输入 GET _settings ,查询可以看到如下
Elasticsearch|ElasticSearch 之初步上手
文章图片

7. Elasticsearch 之 索引操作 具体操作可以查看官方文档
https://www.elastic.co/guide/en/elasticsearch/reference/7.5/indices.html>
官方2版本的中文文档
https://www.elastic.co/guide/cn/elasticsearch/guide/current/index-settings.html
7.1 索引初始化
# 新建一个x1的索引,索引分片数量为5,索引副本数量为1 PUT x1 { "settings": { "index":{ "number_of_shards":5, "number_of_replicas":1 } } }''' number_of_shards 每个索引的主分片数,默认值是 5 。这个配置在索引创建后不能修改。number_of_replicas 每个主分片的副本数,默认值是 1 。对于活动的索引库,这个配置可以随时修改。 '''

Elasticsearch|ElasticSearch 之初步上手
文章图片

# 获取x2索引的配置信息 GET x2/_settings# 获取所有索引的配置信息 GET _all/_settings# 同上 GET _settings

7.2 更新索引
# 修改索引副本数量为2 PUT x2/_settings { "number_of_replicas": 2 }# 如遇到报错:cluster_block_exception # 这是因为由于ES新节点的数据目录data存储空间不足,导致从master主节点接收同步数据的时候失败,此时ES集群为了保护数据,会自动把索引分片index置为只读read-only PUT_all/_settings { "index": { "blocks": { "read_only_allow_delete": false } } }

7.3 删除索引
# 删除x2索引 DELETE x2

8. Elasticsearch 之 映射管理 在Elasticsearch 6.0.0或更高版本中创建的索引只包含一个mapping type。 在5.x中使用multiple mapping types创建的索引将继续像以前一样在Elasticsearch 6.x中运行。 Mapping types将在Elasticsearch 7.0.0中完全删除
8.1 映射介绍
在创建索引的时候,可以预先定义字段的类型及相关属性
Es会根据Json数据源的基础类型,猜测你想要映射的字段,将输入的数据转变成可以搜索的索引项。
Mapping是我们自己定义的字段数据类型,同时告诉es如何索引数据及是否可以被搜索
作用:会让索引建立的更加细致和完善
mysql中有建表语句,es中就是映射管理,即便没有类型,文档可以直接插入
8.2 字段数据类型
类型 说明
string类型 text,keyword
数字类型 long,integer,short,byte,double,float
日期类型 data
布尔类型 boolean
binary类型 binary
复杂类型 object(实体,对象),nested(列表)
geo类型 geo-point,geo-shape(地理位置)
专业类型 ip,competion(搜索建议)
8.3 映射参数
属性 描述 适合类型
store 值为yes表示存储,no表示不存储,默认为yes all
index yes表示分析,no表示不分析,默认为true text
null_value 如果字段为空,可以设置一个默认值,比如"NA"(传过来为空,不能搜索,na可以搜索) all
analyzer 可以设置索引和搜索时用的分析器,默认使用的是standard分析器,还可以使用whitespace,simple。都是英文分析器 all
include_in_all 默认es为每个文档定义一个特殊域_all,它的作用是让每个字段都被搜索到,如果想让某个字段不被搜索到,可以设置为false all
format 时间格式字符串模式 date
8.4 创建索引
text 类型会取出词做倒排索引,keyword 不会被分词,原样存储,原样匹配
mapping 类型一旦确定,以后就不能修改了
# 6.x的版本没问题 PUT books { "mappings": { "book":{ "properties":{ "title":{ "type":"text", "analyzer": "ik_max_word" }, "price":{ "type":"integer" }, "addr":{ "type":"keyword" }, "company":{ "properties":{ "name":{"type":"text"}, "company_addr":{"type":"text"}, "employee_count":{"type":"integer"} } }, "publish_date":{"type":"date","format":"yyy-MM-dd"} } } } }

7.x 版本以后
# 7.x及以上,6.x以后,强制一个索引下只能有一个类型,叫_doc(一个数据库只能建一个表) PUT books { "mappings": { "properties":{ "title":{ "type":"text" }, "price":{ "type":"integer" }, "addr":{ "type":"keyword" }, "company":{ "properties":{ "name":{"type":"text"}, "company_addr":{"type":"text"}, "employee_count":{"type":"integer"} } }, "publish_date":{"type":"date","format":"yyy-MM-dd"} } } }

# 插入文档 PUT books/_doc/1 { "title":"大头儿子小偷爸爸", "price":100, "addr":"北京天安门", "company":{ "name":"我爱北京天安门", "company_addr":"我的家在东北松花江傻姑娘", "employee_count":10 }, "publish_date":"2019-08-19" }# 测试数据2 PUT books/_doc/2 { "title":"白雪公主和十个小矮人", "price":"99", # 写字符串会自动转换 "addr":"黑暗森里", "company":{ "name":"我的家乡在上海", "company_addr":"朋友一生一起走", "employee_count":10 }, "publish_date":"2018-05-19" }PUT books/_doc/3# 这个也可以存 { "age":"白雪公主和十个小矮人", "name":"xwx" }

8.5 查看索引
# 查看books索引的mapping GET books/_mapping# 获取所有的mapping GET _all/_mapping

9. Elasticsearch 的增删查改(CURD) 9.1 CURD 之 Create
PUT xwx/_doc/1 { "name":"顾老二", "age":30, "from": "gu", "desc": "皮肤黑、武器长、性格直", "tags": ["黑", "长", "直"] }PUT xwx/_doc/2 { "name":"熊大", "age":22, "from": "ha", "desc": "小熊一只", "tags": ["黄", "大"] }

Elasticsearch|ElasticSearch 之初步上手
文章图片

注意:当执行PUT命令时,如果数据不存在,则新增该条数据,如果数据存在则修改该条数据。
咱们通过GET命令查询一下:
GET xwx/_doc/1

如果使用 PUT 方式来修改,结果如下所示,会将原本的数据代替导致数据缺失
PUT xwx/_doc/1 { "desc":"皮肤很黄,武器很长,性格很直", "tags":["很黄","很长", "很直"] }

Elasticsearch|ElasticSearch 之初步上手
文章图片

9.2 CURD 之 Update
上面出现的问题,我们先恢复成原装。
PUT xwx/_doc/1 { "name":"顾老二", "age":30, "from": "gu", "desc": "皮肤黑、武器长、性格直", "tags": ["黑", "长", "直"] }

接下来修改需要使用 POST 方法,如下所示,原本的数据不会缺失
POST xwx/_doc/1/_update { "doc": { "desc": "这是修改后", "tags": ["哈哈","哈哈", "哈哈"] } }

Elasticsearch|ElasticSearch 之初步上手
文章图片

现在推荐的写法如下所示
POST /xwx/_update/1 { "doc": { "desc": "这是推荐的写法", "tags": ["哈哈","哈哈", "哈哈"] } }

9.3 CURD 之 Delete
DELETE xwx/_doc/1

通过DELETE命令,就可以删除掉
# 再次获取数值 GET xwx/_doc/1# found:false 表示查询数据不存在 { "_index" : "xwx", "_type" : "_doc", "_id" : "1", "found" : false }

9.4 CURD 之 Retrieve
我们上面已经不知不觉的使用熟悉这种简单查询方式,通过 GET命令查询指定文档:
GET xwx/_doc/1

10. Elasticsearch 之查询的两种方式
  • 查询字符串(query string),简单查询,就像是像传递URL参数一样去传递查询语句,被称为简单搜索或查询字符串(query string)搜索。
  • 另外一种是通过DSL语句来进行查询,被称为DSL查询(Query DSL),DSL是Elasticsearch提供的一种丰富且灵活的查询语言,该语言以json请求体的形式出现,通过restful请求与Elasticsearch进行交互。
数据准备
PUT xwx/_doc/1 { "name":"顾老二", "age":30, "from": "gu", "desc": "皮肤黑、武器长、性格直", "tags": ["黑", "长", "直"] }PUT xwx/_doc/2 { "name":"大娘子", "age":18, "from":"sheng", "desc":"肤白貌美,娇憨可爱", "tags":["白", "富","美"] }PUT xwx/_doc/3 { "name":"龙套偏房", "age":22, "from":"gu", "desc":"mmp,没怎么看,不知道怎么形容", "tags":["造数据", "真","难"] }PUT xwx/_doc/4 { "name":"石头", "age":29, "from":"gu", "desc":"粗中有细,狐假虎威", "tags":["粗", "大","猛"] }PUT xwx/_doc/5 { "name":"魏行首", "age":25, "from":"广云台", "desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!", "tags":["闭月","羞花"] }

Elasticsearch|ElasticSearch 之初步上手
文章图片

10.1 查询字符串
GET xwx/_doc/_search?q=from:gu

还是使用 GET 命令,通过 _serarch 查询,查询条件是什么呢?条件是 from 属性 是 gu 的人都有哪些。别忘了_search 和 from 属性中间的英文分隔符?,结果如下
#! Deprecation: [types removal] Specifying types in search requests is deprecated. { "took" : 19, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 3, "relation" : "eq" }, "max_score" : 0.6329006, "hits" : [ { "_index" : "xwx", "_type" : "_doc", "_id" : "1", "_score" : 0.6329006, "_source" : { "name" : "顾老二", "age" : 30, "from" : "gu", "desc" : "皮肤黑、武器长、性格直", "tags" : [ "黑", "长", "直" ] } }, { "_index" : "xwx", "_type" : "_doc", "_id" : "3", "_score" : 0.6329006, "_source" : { "name" : "龙套偏房", "age" : 22, "from" : "gu", "desc" : "mmp,没怎么看,不知道怎么形容", "tags" : [ "造数据", "真", "难" ] } }, { "_index" : "xwx", "_type" : "_doc", "_id" : "4", "_score" : 0.6329006, "_source" : { "name" : "石头", "age" : 29, "from" : "gu", "desc" : "粗中有细,狐假虎威", "tags" : [ "粗", "大", "猛" ] } } ] } }

我们来重点说下hits,hits 是返回的结果集(如上是所有 from 属性为 gu 的结果集)。重点中的重点是 _score 得分,得分是什么呢?根据算法算出跟查询条件的匹配度,匹配度高得分就高。
10.2 结构化查询
现在使用DSL方式,来完成刚才的查询
GET xwx/_doc/_search { "query": { "match": { "from": "gu" } } }

上例,查询条件是一步步构建出来的,将查询条件添加到 match 中即可,而 match 则是查询所有 from字段的值中含有 gu 的结果就会返回。
11 term 与 match 查询 11.1 match 系列之 match(按条件查询)
match 查询如下所示
GET xwx/_doc/_search { "query": { "match": { "from": "gu" } } }

11.2 match 系列之 match_all(查询全部)
除了按条件查询之外,我们还可以查询 xwx 索引下的 doc 类型中的所有文档,那就是查询全部
GET xwx/_doc/_search { "query": { "match_all": {} } }

match_all 的值为空,表示没有查询条件,那就是查询全部。就像 select * from table_name 一样
11.2 match 系列之 match_phrase(短语查询)
现在已经对 match 有了基本的了解,match 查询的是散列映射,包含了我们希望搜索的字段和字符串。也就说,只要文档中只要有我们希望的那个关键字,但也因此带来了一些问题。
首先来创建一些示例:
PUT t1/_doc/1 { "title": "中国是世界上人口最多的国家" } PUT t1/_doc/2 { "title": "目前美国是世界上军事实力最强大的国家" } PUT t1/_doc/3 { "title": "北京是中国的首都" }

Elasticsearch|ElasticSearch 之初步上手
文章图片

现在,当我们以 中国 作为搜索条件,我们希望只返回和中国相关的文档。首先来使用 match 查询:
GET t1/_doc/_search { "query": { "match": { "title": "中国" } } }

结果如下所示,虽然如期的返回了中国的文档。但是却把和美国的文档也返回了
因为这是 elasticsearch 在内部对文档做分词的时候,对于中文来说,就是一个字一个字分的,所以,我们搜 中国都符合条件,返回,而美国的也符合。
#! Deprecation: [types removal] Specifying types in search requests is deprecated. { "took" : 4, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 3, "relation" : "eq" }, "max_score" : 0.71622837, "hits" : [ { "_index" : "t1", "_type" : "_doc", "_id" : "3", "_score" : 0.71622837, "_source" : { "title" : "北京是中国的首都" } }, { "_index" : "t1", "_type" : "_doc", "_id" : "1", "_score" : 0.6536093, "_source" : { "title" : "中国是世界上人口最多的国家" } }, { "_index" : "t1", "_type" : "_doc", "_id" : "2", "_score" : 0.1656832, "_source" : { "title" : "目前美国是世界上军事实力最强大的国家" } } ] } }

而我们认为中国是个短语,是一个有具体含义的词。所以elasticsearch在处理中文分词方面比较弱势。后面会有对中文的插件。
但目前我们还有办法解决,那就是使用短语查询:
GET t1/_doc/_search { "query": { "match_phrase": { "title": { "query": "中国" } } } }

这里match_phrase是在文档中搜索指定的词组,而中国则正是一个词组,所以愉快的返回了。
那么,现在我们要想搜索中国和世界相关的文档,但又忘记其余部分了,怎么做呢?用 match 也不行,那就继续用 match_phrase 试试:
GET t1/_doc/_search { "query": { "match_phrase": { "title": "中国世界" } } }

很明显结果为空,因为没有中国世界这个短语
我们搜索中国世界这两个指定词组时,但又不清楚两个词组之间有多少别的词间隔。那么在搜的时候就要留有一些余地。这时就要用到了slop了。相当于正则中的中国.*?世界。这个间隔默认为0,导致我们刚才没有搜到,现在我们指定一个间隔
GET t1/_doc/_search { "query": { "match_phrase": { "title": { "query": "中国世界", "slop": 2 } } } }

现在,两个词组之间有了2个词的间隔,这个时候,就可以查询到结果了:
#! Deprecation: [types removal] Specifying types in search requests is deprecated. { "took" : 3, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 0.99876255, "hits" : [ { "_index" : "t1", "_type" : "_doc", "_id" : "1", "_score" : 0.99876255, "_source" : { "title" : "中国是世界上人口最多的国家" } } ] } }

11.3 match 系列之 match_phrase_prefix(最左前缀查询)
当准备搜索 beautiful girl 词语时。但单词 beautiful 拼到 bea 就不知道往下怎么拼了。这个时候,elasticsearch 就可以看自己的词库有啥 bea 开头的词,结果还真发现了两个:
准备数据
PUT t3/_doc/1 { "title": "maggie", "desc": "beautiful girl you are beautiful so" } PUT t3/_doc/2 { "title": "sun and beach", "desc": "I like basking on the beach" }

Elasticsearch|ElasticSearch 之初步上手
文章图片

但这里用 match 和 match_phrase 都不太合适,因为输入的不是完整的词。
可以用 match_phrase_prefix 来搞:
GET t3/_doc/_search { "query": { "match_phrase_prefix": { "desc": "bea" } } }

结果如下
#! Deprecation: [types removal] Specifying types in search requests is deprecated. { "took" : 4, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 2, "relation" : "eq" }, "max_score" : 0.9530774, "hits" : [ { "_index" : "t3", "_type" : "_doc", "_id" : "1", "_score" : 0.9530774, "_source" : { "title" : "maggie", "desc" : "beautiful girl you are beautiful so" } }, { "_index" : "t3", "_type" : "_doc", "_id" : "2", "_score" : 0.6931472, "_source" : { "title" : "sun and beach", "desc" : "I like basking on the beach" } } ] } }

前缀查询是短语查询类似,但前缀查询可以更进一步的搜索词组,只不过它是和词组中最后一个词条进行前缀匹配(如搜这样的 you are bea)。应用也非常的广泛,比如搜索框的提示信息,当使用这种行为进行搜索时,最好通过 max_expansions 来设置最大的前缀扩展数量,因为产生的结果会是一个很大的集合,不加限制的话,影响查询性能。
GET t3/_doc/_search { "query": { "match_phrase_prefix": { "desc": { "query": "bea", "max_expansions": 1 } } } }

【Elasticsearch|ElasticSearch 之初步上手】结果如下
{ "took" : 0, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : { "value" : 1, "relation" : "eq" }, "max_score" : 0.6931472, "hits" : [ { "_index" : "t3", "_type" : "_doc", "_id" : "2", "_score" : 0.6931472, "_source" : { "title" : "sun and beach", "desc" : "I like basking on the beach" } } ] } }

    推荐阅读