文章目录

  • 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对比

  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在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字

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

官方网站:https://www.elastic.co/cn/downloads/elasticsearch



三、 启动 es

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

启动完可以测试,如下所示:

在浏览器输入以下地址:http://127.0.0.1:9200/,可以看到以下内容

如果在运行中出现如下异常

只需要将 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/

5.4 配置跨域

修改 Elasticsearch 安装目录中 config 文件夹下 elasticsearch.yml 文件,加入下面两行:

添加配置时,:后必须空格,不然启动闪退

http.cors.enabled: true
http.cors.allow-origin: "*"

启动 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

到相应地址,下载即可,解压下载后的文件

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


在 console 中输入 GET _settings ,查询可以看到如下

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 。对于活动的索引库,这个配置可以随时修改。
'''

# 获取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": ["黄", "大"]
}

注意:当执行PUT命令时,如果数据不存在,则新增该条数据,如果数据存在则修改该条数据。

咱们通过GET命令查询一下:

GET xwx/_doc/1

如果使用 PUT 方式来修改,结果如下所示,会将原本的数据代替导致数据缺失

PUT xwx/_doc/1
{"desc":"皮肤很黄,武器很长,性格很直","tags":["很黄","很长", "很直"]
}

9.2 CURD 之 Update

上面出现的问题,我们先恢复成原装。

PUT xwx/_doc/1
{"name":"顾老二","age":30,"from": "gu","desc": "皮肤黑、武器长、性格直","tags": ["黑", "长", "直"]
}

接下来修改需要使用 POST 方法,如下所示,原本的数据不会缺失

POST xwx/_doc/1/_update
{"doc": {"desc": "这是修改后","tags": ["哈哈","哈哈", "哈哈"]}
}

现在推荐的写法如下所示

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":["闭月","羞花"]
}

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": "北京是中国的首都"
}


现在,当我们以 中国 作为搜索条件,我们希望只返回和中国相关的文档。首先来使用 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"
}


但这里用 matchmatch_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}}}
}

结果如下

{"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"}}]}
}

ElasticSearch 之初步上手相关推荐

  1. 微信小程序云开发初步上手

    微信小程序云开发初步上手 1.概述 2019年11月6-7日,我报名参加了腾讯开发者大会举办的"2019年小程序.云开发极限编程"活动,英文名为"CloudBase Ha ...

  2. Elasticsearch学习1 入门进阶 Linux系统下操作安装Elasticsearch Kibana 初步检索 SearchAPI Query DSL ki分词库 自定义词库

    文章目录 一.全文检索-Elasticsearch 1.Elasticsearch简介 2.全文搜索引擎 二.docker安装 1.elasticsearch启动 2.kibana启动 三.[入门]初 ...

  3. Spring框架学习笔记(1) ---[spring框架概念 , 初步上手使用Spring , 控制反转 依赖注入初步理解 ]

    spring官网 -->spring官网 spring5.3.12–>spring-framework 在线文档 --> Spring 5.3.12 文章目录 1.Spring概论 ...

  4. yii2-elasticsearch(3)yii2 elasticsearch 的初步尝试

    配置 return [//....'components' => ['elasticsearch' => ['class' => 'yii\elasticsearch\Connect ...

  5. ei capitan mysql_OSX 10.11 EI Capitan初步上手体验以及开发环境配置

    国庆放假在家,第一时间就升级了10.11,把玩了几天,也攻克了一些与开发环境相关的问题,在此跟大家分享一下. 作为一名开发人员,还是先谈谈与开发环境相关的问题吧.截止到目前发现了两个问题,可能会影响正 ...

  6. Pycharm初步上手

    1.Pycharm安装 于jetbrains官网https://www.jetbrains.com/下载了Pycharm Edu 2020.3版本. 2.配置中文环境 由于英语太烂,遂改成中文环境. ...

  7. 全文搜索引擎选 ElasticSearch 还是 Solr

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 来源:http://t.cn/Ebgm7sn 最近项目组安排了一个任务,项目中用到了全文搜索,基于全文 ...

  8. 终于有人把 Elasticsearch 原理讲透了

    上个世纪末,我在广州做 PHP 程序员,那会儿程序员的门槛真低啊.我的上司是技术经理,非常照顾我.有个客户是开律所的,过来提了一个私活的需求,要做个法律查询的网站. 上司让我赚点外块,说干就干,整个 ...

  9. 全文搜索引擎选 ElasticSearch 还是 Solr?

    最近项目组安排了一个任务,项目中用到了基于 Solr 的全文搜索,但是该 Solr 搜索云项目不稳定,经常查询不出来数据,需要手动全量同步. 而且它还是其他团队在维护,依赖性太强,导致 Solr 服务 ...

最新文章

  1. 「仅凭照片就能判断一个人是否犯罪」?这样的研究能发表,LeCun、MIT谷歌等机构的1700名研究者怒了...
  2. 深入理解ROS技术 【3】ROS下的模块详解(129-180)
  3. 计算机图形学学习报告,计算机图形学学习报告.pdf
  4. mysql数据库操作语句大全
  5. 你不得不看的六篇知识图谱落地好文
  6. Android 用户信息管理程序【SQLite数据库、多选框、单选按钮】
  7. AI+游戏:高效利用样本的强化学习 | 腾讯AI Lab学术论坛演讲
  8. 超松弛迭代法(C语言实现)
  9. mysql动态加载数据库数据库_Mysql动态更新数据库脚本的示例讲解
  10. bzoj1783: [Usaco2010 Jan]Taking Turns
  11. [翻译]深入解析Windows操作系统(下)之第十章 内存管理
  12. 2017 Multi-University Training Contest 5 solutions BY 吉如一
  13. 便签pc android同步,微软电脑sticky notes便签软件怎么和安卓手机便签同步?
  14. 服务器虚拟网卡驱动卸载,Win10安装和卸载万能网卡版驱动的方法
  15. wifi信号衰减与距离关系_(1)WIFI信号确定距离
  16. C# 实现俄罗斯方块
  17. p2p网络测试工具_(官方更新)IPFS的网络层——libp2p在2020的发展
  18. jquery水平导航栏动态菜单
  19. 使用Processing实现井字棋
  20. 【ROM定制】Android 12 制作『MIUI官改』那点事①了解

热门文章

  1. 三角形判断(直角,等边,一般)
  2. 020:Python函数使用进阶
  3. IDEA this license K71U8DBPNE has bean cancelled
  4. 一个工程师的“噩梦”:刚分清CPU、GPU,却发现还有更多...
  5. 用Python实现电脑与手机之间的文件快速传输
  6. 2021SC@SDUSC PALISADE开源库(二)CKKS讲解系列(一)普通编码和解码
  7. plsql报错,缓存超限制(ORA-20000:ORU-10027:buffer overflow,limit of 10000 bytes) 解决方法
  8. 神七飞天与我的一段往事
  9. 扇贝编程python学习笔记-基础篇10
  10. ASP.NET Core中使用滑动窗口限流