ElasticSearch学习
一、搜索与ElasticSearch
1、什么是搜索
在任何场景下,找寻你想要的信息,这个时候,会输入一段你要搜索的关键字,然后就期望找到这个关键字相关的有些信息
2、数据库搜索
缺点:
1)每条记录的指定字段文本可能会很长,需要对每条记录的所有文本进行扫描,来判断说是否符合;太耗时耗资源
2)还不能将搜索词拆分开来;比如输入“生化机”,就搜索不出来“生化危机”
3、什么是全文检索和Lucene
1)全文检索:倒排索引
2)lucene:就是一个jar包
;里面包含了封装好的各种建立倒排索引,以及进行搜索的代码,包括各种算法。我们就用java开发的时候,引入lucene jar,然后基于lucene的api进行去进行开发就可以了。用lucene,我们就可以去将已有的数据建立索引,lucene会在本地磁盘上面,给我们组织索引的数据结构。另外的话,我们也可以用lucene提供的一些功能和api来针对磁盘上的索引数据来进行搜索
4、什么是ElasticSearch
一个分布式,高性能,高可用,可伸缩的搜索和分析系统
5、ElasticSearch的功能、适用场景、特点
1)ElasticSearch的功能:
(1)分布式的搜索引擎和数据分析引擎
(2)全文检索,结构化检索,数据分析
(3)对海量数据进行近实时的处理
2)ElasticSearch的适用场景:
(1)百度百科
(2)新闻网站
(3)电商网站
。
。
。
3)ElasticSearch的特点:
(1)可作为分布式集群
,也可作为单机
服务小系统
(2)并非新技术
,而是将全文检索、分布式、数据分析等技术合并在一起的一种技术;如同SpringCloud
(3)对用户来说,是可以开箱即用
的;部署简单,操作简单
(4)提供了传统数据库所欠缺的一些功能;如:近实时性、海量数据、数据分析、全文检索、同义词处理、相关度排名等等
6、ElasticSearch的核心概念
1)Lucene和ElasticSearch的前世今生:
(1)Lucene:最先进、功能最强大的搜索库,直接基于Lucene开发,非常复杂,api复杂(实现一些简单的功能,写大量的java代码),需要深入理解原理(各种索引结构)
(2)ElasticSearch:基于Lucene
,隐藏复杂性,提供简单易用的restful api接口、java api接口(还有其他语言的api接口)
分布式的文档存储引擎
分布式的搜索引擎和分析引擎
分布式,支持PB级数据
开箱即用,优秀的默认参数,不需要任何额外设置,完全开源
关于Elasticsearch的一个 传说 (发展):
有一个程序员失业了,陪着自己老婆去英国伦敦学习厨师课程。程序员在失业期间想给老婆写一个菜谱搜索引擎,觉得Lucene实在太复杂了,就开发了一个封装了Lucene的开源项目,Compass。后来程序员找到了工作,是做分布式的高性能项目的,觉得Compass不够,就写了ElasticSearch,让Lucene变成分布式的系统。
2)ElasticSearch的核心概念
:
(1)Near Realtime(NRT):近实时;两个意思:从写入数据到数据可以被搜索到有一个小延迟(大概1秒),基于es执行搜索和分析可以达到秒级
近实时第一种情况的图解
:
(2)Cluster:集群
,包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常
(3)Node:节点
,集群中的一个节点,节点也有一个名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为“elasticsearch”的集群,如果直接启动一堆节点,那么它们会自动组成一个ElasticSearch集群,当然一个节点也可以组成一个ElasticSearch集群
(4)Document & Field:文档 & 字段
,es中的最小数据单元,一个Document可以是一条客户数据,一条订单数据,通常用JSON结构表示。一个Document里有多个Field,每个Field就是一个数据字段。
(5)Index:索引
,包含一堆有相似结构的文档数据,比如可以有一个客户索引,订单索引。一个Index包含很多Document,一个Index就代表了一类类似的或者相同的Document。
(6)Type:类型,es7.x版本中被移除了此概念
。每个索引里都可以有一个或多个Type,Type是Index中的一个逻辑数据分类,一个Type下的Document,都有相同的Field。比如博客系统,有一个索引,可以定义用户数据Type,博客数据Type,评论数据Type。
商品Type可以有:日化商品Type,电器商品Type,生鲜商品Type
日化商品Type:product_id,product_name,product_desc,category_id,category_name
电器商品Type:product_id,product_name,product_desc,category_id,category_name,service_period
生鲜商品Type:product_id,product_name,product_desc,category_id,category_name,eat_period
每一个Type里面,都会包含一堆Document
(7)Shard:本名为Primary Shard
。单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个Shard,分布在多台服务器上存储。有了Shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。
(8)Replica:本名为Replica Shard
。任何一个服务器随时可能故障或宕机,此时Shard可能就会丢失,因此可以为每个Shard创建多个Replica副本。Replica可以在Shard故障时提供备用服务,保证数据不丢失,多个Replica还可以提升搜索操作的吞吐量和性能。Primary Shard(建立索引时一次设置,不能修改,默认5个),Replica Shard(随时修改数量,默认1个),默认每个索引10个Shard,5个Primary Shard,5个Replica Shard,最小的高可用配置,是2台服务器
。
Shard 与 Replica 的图解
:
3)ElasticSearch与数据库的概念比较:
ElasticSearch | 数据库 |
---|---|
Field | 字段 |
Document | 行 |
Type | 表 |
Index | 库 |
7、ElasticSearch、Kibana的安装、启动(两者版本要一样)
1)安装JDK,至少1.8.0_73以上版本,java -version
2)下载和解压缩ElasticSearch安装包,目录结构
3)启动Elasticsearch:进入ElasticSearch文件的bin路径下,运行elasticsearch.bat
。es本身特点之一就是开箱即用,如果是中小型应用,数据量少,操作不是很复杂,直接启动就可以用了
4)检查ES是否启动成功:http://localhost:9200/?pretty
name: 节点名称
cluster_name: 集群名称(默认的集群名称就是elasticsearch)
version.number: es版本号
{
"name": "4onsTYV",
"cluster_name": "elasticsearch",
"cluster_uuid": "nKZ9VK_vQdSQ1J0Dx9gx1Q",
"version": {
"number": "5.2.0",
"build_hash": "24e05b9",
"build_date": "2017-01-24T19:52:35.800Z",
"build_snapshot": false,
"lucene_version": "6.4.0"
},
"tagline": "You Know, for Search"
}
5)修改集群名称:config文件夹的elasticsearch.yml
文件
6)下载和解压缩Kibana安装包,使用里面的开发界面,去操作ElasticSearch,作为我们学习es知识点的一个主要的界面入口
7)启动Kibana:进入Kibana文件的bin路径下,运行kibana.bat
。
8)进入Dev Tools界面:http://localhost:5601
9)GET _cluster/health:获取ElasticSearch的运行健康状况
二、快速入门案例实战之电商网站商品管理
1、集群健康检查、 CRUD操作(所有指令区分大小写)
1)Document数据格式:json格式
(1)应用系统的数据结构都是面向对象的,复杂的
(2)对象数据存储到数据库中,只能拆解开来,变为扁平的多张表,每次查询的时候还得还原回对象格式,相当麻烦
(3)ES是面向文档的,文档中存储的数据结构,与面向对象的数据结构是一样的,基于这种文档数据结构,ES可以提供复杂的索引,全文检索,分析聚合等功能
(4)ES的Document用json数据格式来表达
2)电商网站商品管理案例背景介绍:
有一个电商网站,需要为其基于ES构建一个后台系统,提供以下功能:
(1)对商品信息进行CRUD(增删改查)操作
(2)执行简单的结构化查询
(3)可以执行简单的全文检索,以及复杂的phrase(短语)检索
(4)对于全文检索的结果,可以进行高亮显示
(5)对数据进行简单的聚合分析
3)简单的集群管理
(1)快速检查集群的健康状况:
- ES提供了一套api,叫做
cat api
,可以查看ES中各种各样的数据
GET /_cat/health?v
如何快速了解集群的健康状况?green、yellow、red
?
green:每个索引的Primary Shard和Replica Shard都是启动活跃(active)状态的
yellow:每个索引的Primary Shard都是启动活跃(active)状态的,但是部分Replica Shard不是启动活跃(active)状态,处于不可用的状态
red:不是所有索引的Primary Shard都是启动活跃(active)状态的,部分索引有数据丢失了
5.x版本:启动一个ES,默认生成一个
索引;要求需要
有Replica Shard
7.x版本:启动一个ES,默认生成三个
索引;不需要
有Replica Shard
启动一台ES:用shards(即Shards)减去pri(Primary Shard),就是Replica Shard。三者均为实际启动了的
epoch | timestamp | cluster | status | node.total | node.data | shards | pri | relo | init | unassign | pending_tasks | max_task_wait_time | active_shards_percent |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1584755228 | 01:47:08 | elasticsearch | green | 1 | 1 | 3 | 3 | 0 | 0 | 0 | 0 | - | 100.0% |
启动凉台ES:用shards(即Shards)减去pri(Primary Shard),就是Replica Shard。三者均为实际启动了的
epoch | timestamp | cluster | status | node.total | node.data | shards | pri | relo | init | unassign | pending_tasks | max_task_wait_time | active_shards_percent |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1584756567 | 02:09:27 | elasticsearch | green | 2 | 3 | 6 | 3 | 0 | 0 | 0 | 0 | - | 100.0% |
- 快速查看集群中的索引:
GET /_cat/indices?v
启动一台ES:用pri(Primary Shard)加上rep(Replica Shard),就是Shards。三者均为需要启动的
health | status | index | uuid | pri | rep | docs.count | docs.deleted | store.size | pri.store.size |
---|---|---|---|---|---|---|---|---|---|
green | open | .kibana_task_manager_1 | UNGZfmkTRE-izXImlR-qow | 1 | 0 | 2 | 1 | 26.8kb | 26.8kb |
green | open | .apm-agent-configuration | SOvLxZQfTWKQJrd1eRo-sw | 1 | 0 | 0 | 0 | 283b | 283b |
green | open | .kibana_1 | V4X36I1ZQ3-wZozP2JPMUQ | 1 | 0 | 22 | 10 | 47.6kb | 47.6kb |
启动两台ES:用pri(Primary Shard)加上rep(Replica Shard),就是Shards。三者均为需要启动的
health | status | index | uuid | pri | rep | docs.count | docs.deleted | store.size | pri.store.size |
---|---|---|---|---|---|---|---|---|---|
green | open | .kibana_task_manager_1 | UNGZfmkTRE-izXImlR-qow | 1 | 1 | 2 | 1 | 53.7kb | 26.8kb |
green | open | .apm-agent-configuration | SOvLxZQfTWKQJrd1eRo-sw | 1 | 1 | 0 | 0 | 283b | 283b |
green | open | .kibana_1 | V4X36I1ZQ3-wZozP2JPMUQ | 1 | 1 | 22 | 10 | 101.9kb | 50.9kb |
- 简单的索引操作
创建索引:PUT /test_index?pretty
删除索引:DELETE /test_index?pretty
4)Document的CRUD操作:
(1)新增Document:ES会自动建立
index,不需要提前创建,而且ES默认会对Document每个Field都建立倒排索引
,让其可以被搜索
PUT /{index}/_doc/{id}
{
"json数据"
}
(2)删除Document:
DELETE /{index}/_doc/{id}
(3)修改Document:
替换Document:替换方式有一个不好,即使必须带上所有的Field
,才能去进行信息的修改
PUT /{index}/_doc/{id}
{
"json数据"
}
更新Document:
POST /{index}/_doc/{id}
{
"json数据"
}
(4)查询Document:
GET /{index}/_doc/{id}
2、多种搜索方式
事先了解搜索的结果结构
:
took:耗费了几毫秒
timed_out:是否超时,这里是没有
_shards:数据拆成了1个分片,所以对于搜索请求,会打到所有的Primary Shard(或者是它的某个Replica Shard也可以)
hits.total:查询结果的数量,1个Document
hits.max_score:score的含义,就是Document对于一个search的相关度的匹配分数,越相关,就越匹配,分数也高
hits.hits:包含了匹配搜索的Document的详细数据
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1,
"hits": [
{
"_index": "test_index",
"_type": "_doc",
"_id": "1",
"_score": 1,
"_source": {
"name": "chengqb",
"desc": "ceshi",
"price": 30,
"producer": "gaolujie producer",
"tags": [
"meibai",
"fangzhu"
]
}
}
]
}
}
1)query string search:适用于命令行界面
GET /{index}/_search
参数处理:search参数都是以http请求的query string来附带的
如:搜索商品名称中包含yagao的商品,而且按照售价降序排序:
GET /{index}/_search?q=name:yagao&sort=price:desc
适用场景:适用于临时的在命令行使用一些工具,比如curl,快速的发出请求,来检索想要的信息;但是如果查询请求很复杂,是很难去构建的
在生产环境中,几乎很少使用query string search
2)query DSL:适用于生产环境
DSL
:Domain Specified Language,特定领域的语言
http request body
:请求体,可以用json的格式来构建查询语法,比较方便,可以构建各种复杂的语法
查询所有Document
:
GET /{index}/_search
{
"query": { "match_all": {} }
}
条件查询并排序
:
GET /{index}/_search
{
"query" : {
"match" : {
{Field} : {value}
}
},
"sort": [
{
{Field} : "desc" / "asc"
}
]
}
分页查询
:
GET /{index}/_search
{
"query": { "match_all": {} },
"from": {value},
"size": {value}
}
指定返回字段
:
GET /{index}/_search
{
"query": { "match_all": {} },
"_source": [{Field}]
}
3)query filter:
GET /{index}/_search
{
"query" : {
"bool" : {
"must" : {
"match" : {
{Field} : {value}
}
},
"filter" : {
"range" : {
{Field} : { "gt" : {value}}
}
}
}
}
}
4)full-text search(全文检索):建立倒排索引,搜索词也会被拆解,可以只包含被拆解后的几部分(一部分以上)
GET /{index}/_search
{
"query" : {
"match" : {
{Field} : {value}
}
}
}
5)phrase search(短语搜索):搜索词不会被拆解,必须包含一模一样的
GET /{index}/_search
{
"query" : {
"match_phrase" : {
{Field} : {value}
}
}
}
6)highlight search(高亮搜索):高亮搜索结果
GET /{index}/_search
{
"query" : {
"match" : {
{Field} : {value}
}
},
"highlight": {
"fields" : {
{Field} : {}
}
}
}