ElasticSearch-全文检索快速入门
官网https://www.elastic.co/cn/what-is/elasticsearch
**全文搜索属于最常见的需求,开源的 Elasticsearch 是目前全文搜索引擎的首选。
它可以快速地储存、搜索和分析海量数据。**维基百科、Stack Overflow、Github 都采用它。
Elastic 是 Lucene 的封装,提供了 REST API (天然的跨平台)的操作接口,开箱即用。
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
官方中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html
社区中文:
https://es.xiaoleilu.com/index.html
http://doc.codingdict.com/elasticsearch/0/
是什么?
一个全文搜索引擎。
有什么用?
海量数据全文搜索、存储、分析。
解决什么问题?
当下技术存储数据查找搜索慢。
场景
- 大量数据搜索
- 日志记录分析
在8.0版本正式删除类型概念。
#elasticSearch
一、基本概念
1、Index(索引)
相当于MySQL的库概念
2、Type(类型)
相当于MySQL的Table概念
3、Document(文档)
文档为 JSON 格式,Document 就像是 MySQL 中的某个 Table 里面的内容
4、倒排索引机制
使用分词技术分词,存储分词和相关文档记录。能极大提高相关查询效率。
二、Docker 安装 ES
1、下载镜像文件
docker pull elasticsearch:7.4.2
存储和检索数据
docker pull kibana:7.4.2
可视化检索数据
2、创建实例
1.ElasticSearch
# 创建ES配置目录
mkdir -p /home/hacah/dockerdata/elasticsearch/config
mkdir -p /home/hacah/dockerdata/elasticsearch/data
echo "http.host: 0.0.0.0" >> /home/hacah/dockerdata/elasticsearch/config/elasticsearch.yml
# 保证权限
chmod -R 777 /home/hacah/dockerdata/elasticsearch/
# 启动
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx512m" \
-v /home/hacah/dockerdata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /home/hacah/dockerdata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /home/hacah/dockerdata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2
特别注意:
-e ES_JAVA_OPTS=“-Xms64m -Xmx512m” \ 测试环境下,设置 ES 的初始内存和最大内存。
2.Kibana
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.31.158:9200 -p 5601:5601 \
-d kibana:7.4.2
三、基础使用
1._cat
使用
GET /_cat/nodes
:查看所有节点GET /_cat/health
:查看 es 健康状况GET /_cat/master
:查看主节点GET /_cat/indices
:查看所有索引
2、索引一个文档(保存)
指定保存在哪个索引的哪个类型下,指定用哪个唯一标识。
PUT customer/external/1 是在 customer 索引下的 external 类型下保存 1 号数据
保存可以使用PUT或POST请求
POST :可以新增可以修改。如果不指定 id,会自动生成 id,指定 id 就会修改这个数据,并新增版本号。
# 不指定id
http://192.168.31.158:9200/customer/external
# 指定id
http://192.168.31.158:9200/customer/external/2
PUT: 可以新增可以修改,但一定需要指定id,不指定 id 会报错。由于 PUT 需要指定 id,我们一般都用来做修改操作,请求url方式与post一样。
3、查询文档
GET customer/external/1
{
"_index": "customer",//在哪个索引
"_type": "external",//在哪个类型
"_id": "1",//记录 id
"_version": 2,//版本号
"_seq_no": 1,//并发控制字段,每次更新就会+1,用来做乐观锁
"_primary_term": 1,//同上,主分片重新分配,如重启,就会变化
"found": true,
"_source": {
//真正的内容
"name": "John Doe"
}
}
4、更新文档
POST有两种操作:
POST customer/external/1/_update
{
"doc":{
"name": "John de" // 更新内容
}
}
其中的doc结构是固定的,更新的数据在其中。
第二种:
POST customer/external/1
{
"name": "John dt" // 更新内容
}
如何确定使用哪种呢?
基于场景,对于大并发更新,不带 update;
对于大并发查询偶尔更新,带 update;对比更新,重新计算分配规则。
PUT只能使用不带_update的更新且用法与POST类似。
5、删除文档&索引
# 删除文档
DELETE customer/external/1
# 删除索引
DELETE customer
6、bulk 批量 API
bulk用于批量操作,使用操作如下:
POST customer/external/_bulk
{ action: { metadata }}\n
{ request body}\n
url添加_bulk,请求体中两条数据为一个操作。
比如:
POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title":"My first blog post" }
{ "index":{ "_index": "website", "_type": "blog" }}
{ "title":"My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }
{ "doc" : {"title" : "My updated blog post"} }
在kibana执行以上指令。
bulk API 以此按顺序执行所有的 action(动作)。如果一个单个的动作因任何原因而失败,
它将继续处理它后面剩余的动作。当 bulk API 返回时,它将提供每个动作的状态。
7、样本测试数据
顾客银行账户信息的虚构的 JSON文档样本
POST bank/account/_bulk
https://github.com/elastic/elasticsearch/blob/7.4/docs/src/test/resources/accounts.json
执行上面的数据指令。
四、进阶检索
1、SearchAPI
ES 支持两种基本方式检索 :
- 一个是通过使用 REST request URI
发送搜索参数(uri+检索参数) - 另一个是通过使用
REST request body 来发送它们(uri+请求体)
检索信息
uri参数检索
# 检索 bank 下所有信息,包括 type 和 docs
GET bank/_search
# 请求参数方式检索
GET bank/_search?q=*&sort=account_number:asc
# 得到的响应属性解析
took - Elasticsearch 执行搜索的时间(毫秒)
time_out - 告诉我们搜索是否超时
_shards - 告诉我们多少个分片被搜索了,以及统计了成功/失败的搜索分片
hits - 搜索结果
hits.total - 搜索结果
hits.hits - 实际的搜索结果数组(默认为前 10 的文档)
sort - 结果的排序 key(键)(没有则按 score 排序)
score 和 max_score –相关性得分和最高得分(全文检索用)
请求体进行检索
GET bank/_search
{
"query": {
"match_all": {
}
},
"sort": [
{
"account_number": {
"order": "desc"
}
}
]
}
使用请求工具就改为POST请求。
2、Query DSL
Elasticsearch 提供了一个可以执行查询的 Json 风格的 DSL(domain-specific language 领域特
定语言)。这个被称为 Query DSL。
一个查询语句的典型结构:
{
QUERY_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
如果是针对某个字段,那么它的结构如下:
{
QUERY_NAME: {
FIELD_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}
使用例子:
GET bank/_search
{
"query": {
"match_all": {}
},
"from": 0,
"size": 5,
"sort": [
{
"account_number": {
"order": "desc"
}
}
],
"_source": ["age","balance"]
}
-
query 定义如何查询,
-
match_all 查询类型【代表查询所有的所有】,es 中可以在 query 中组合非常多的查
询类型完成复杂查询 -
除了 query 参数之外,我们也可以传递其它的参数以改变查询结果。如 sort,size
-
from+size 限定,完成分页功能
-
sort 排序,多字段排序,会在前序字段相等时后续字段内部排序,否则以前序为准
-
"_source"定义返回字段
1 match(匹配查询)
可以分为数值匹配和字符串全文索引,数值匹配会查询完全相同的数据,而字符串全文索引会按分词查询相关度的数据(需要使用单词查询)。
基本类型(非字符串),精确匹配:
GET bank/_search
{
"query": {
"match": {
"balance": "16418"
}
}
}
字符串全文索引
GET bank/_search
{
"query": {
"match": {
"address": "Road 263"
}
}
}
查询出相关数据与相关度得分。
2 match_phrase(短语匹配)
短语匹配会把查询值当做不可分割的整体查询,即对比match来说不进行分词查询,把短语作为整体查询出相关度。
GET bank/_search
{
"query": {
"match_phrase": {
"address": "Aviation Road"
}
}
}
查询包含Aviation Road
的数据。
3 multi_match(多字段匹配)
match的多字段版本
GET bank/_search
{
"query": {
"multi_match": {
"query": "Road",
"fields": ["address", "state"]
}
}
}
查询 address或者state两个字段的匹配Road数据。
4 bool(复合查询)
复合语句可以合并任何其它查询语句,包括复合语句,复合语句之间可以互相嵌套,可以表达非常复杂的逻辑。
- must:必须达到 must 列举的所有条件
- should:应该达到 should 列举的条件,如果达到会增加相关文档的评分,不改变查询结果
- must_not 必须不是指定的情况
GET bank/_search
{
"query":