一 Elasticsearch的简介和安装
1.1 Elasticsearch是什么
Elaticsearch简称为ES,是一个开源的可扩展的分布式的全文检索引擎,它可以近乎实时的存储、检索数据。本身扩展性很好,可扩展到上百台服务器,处理PB级别的数据。
ES使用Java开发并使用Lucene作为其核心来实现索引和搜索的功能,但是它通过简单的RestfulAPI和javaAPI来隐藏Lucene的复杂性,从而让全文搜索变得简单。
起源:Shay Banon。2004年失业,陪老婆去伦敦学习厨师。失业在家帮老婆写一个菜谱搜索引擎。封装了lucene,做出了开源项目compass。找到工作后,做分布式高性能项目,再封装compass,写出了elasticsearch,使得lucene支持分布式。现在是Elasticsearch创始人兼Elastic首席执行官。
1.2 Elasticsearch的功能
1 分布式的搜索引擎
分布式:Elasticsearch自动将海量数据分散到多台服务器上去存储和检索
2 全文检索
提供模糊搜索等自动度很高的查询方式,并进行相关性排名,高亮等功能
3 数据分析引擎(分组聚合)
最近一周笔记本电脑这种商品销量排名top10的商家有哪些?最近1个月访问量排名top3的新闻板块是哪些?
4 对海量数据进行近实时的处理
因为是分布式架构,Elasticsearch可以采用大量的服务器去存储和检索数据。可以实现秒级别的数据搜索和分析
1.3 Elasticsearch的优点
Elasticsearch的特点是它提供了一个极速的搜索体验。这源于它的高速(speed)。相比较其它的一些大数据引擎,Elasticsearch可以实现秒级的搜索,速度非常有优势。Elasticsearch的cluster是一种分布式的部署,极易扩展(scale )这样很容易使它处理PB级的数据库容量。最重要的是Elasticsearch是它搜索的结果可以按照分数进行排序,它能提供我们最相关的搜索结果(relevance) 。
1.4 安装Elasticsearch Kibana
在阿里云上开放端口
9200 9300 5601
下载镜像
docker pull elasticsearch:7.4.2
docker pull kibana:7.4.2
创建ES实例
mkdir -p /mydata/elasticsearch/config
mkdir -p /mydata/elasticsearch/data
chmod 777 -R /mydata/elasticsearch
echo "http.host: 0.0.0.0">>/mydata/elasticsearch/config/elasticsearch.yml
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms84m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -v /mydata/elasticsearch/data:/usr/share/elasticsearch/data -v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins -d elasticsearch:7.4.2
创建kibanna实例
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://外网ip:9200 -p 5601:5601 -d kibana:7.4.2
服务器重启 容器自动运行
docker update elasticsearch --restart=always
docker update kibana --restart=always
查看elasticsearch 和 kiban容器是否正在运行
docker ps
1.5 安装中文分词器
下载ik分词器
切换文件夹
cd /usr/software
/usr/software文件夹下创建ik文件夹
mkdir ik
切换到ik文件夹
cd ik
在此文件夹下 下载elasticsearch-analysis-ik-7.4.2.zip中文分词器
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
解压安装分词器
安装unzip命令
yum install unzip解压 elasticsearch-analysis-ik-7.4.2.zip
unzip elasticsearch-analysis-ik-7.4.2.zip删除ik文件夹下的所有的zip文件(删除ik文件夹下的: elasticsearch-analysis-ik-7.4.2.zip)
rm -rf *.zip#将ik文件夹移动到 /mydata/elasticsearch/plugins文件夹下
cd ..
mv ik /mydata/elasticsearch/plugins重启下elasticsearch容器
docker restart elasticsearch
查看当前正在运行的容器,如果没有看到elasticsearch
docker ps
使用以下命令查看elasticsearch容器的日志
docker logs elasticsearch
使用kibana测试中文分词器浏览器中输入地址 http://自己的IP地址:5601/
POST _analyze
{
"analyzer": "ik_max_word",
"text": "南京市长江大桥"
}
运行结果
{
"tokens" : [
{
"token" : "南京",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "长江大桥",
"start_offset" : 2,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "长江",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "大桥",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 3
}
]
}
1.6 扩展词典
1 cd /mydata/elasticsearch/plugins/ik/config 目录下,新增自定义词典
vim ext_dict.dic
按i键
输入: 江大桥
按"ESC"键
按:键 输入wq回车
2 vi IKAnalyzer.cfg.xml 添加内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">ext_dict.dic</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords"></entry>
<!--用户可以在这里配置远程扩展字典 -->
<!-- <entry
key="remote_ext_dict">http://192.168.211.130:8080/tag.dic</entry> -->
<!--用户可以在这里配置远程扩展停止词字典-->
<!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>
3 重启elasticsearch容器稍后片刻
docker restart elasticsearch
分词结果中出现了自定义分词 江大桥
{
"tokens" : [
{
"token" : "南京",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "长江大桥",
"start_offset" : 2,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "长江",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "江大桥",
"start_offset" : 3,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "大桥",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 4
},
{
"token" : "doc",
"start_offset" : 6,
"end_offset" : 9,
"type" : "ENGLISH",
"position" : 5
}
]
1.7 Elasticsearch的基本概念
node
节点,部署Elasticsearch程序的服务器cluster
集群,多个节点组成的架构index
索引,相当于关系型数据库的databasetype
类型,对应于关系型数据库的tabledocument
文档,类似于关系型数据库的row
文档三元素
_index:文档对应的索引
_type:文档对应的类型
_ID:文档的唯一ID
二 Elasticsearch的快速实战
2.1 查看信息
GET _cat/indices 查看所有索引
GET _cat/nodes 查看所有节点
GET _cat/health 查看ES的健康状态
2.2 新增记录
PUT /索引的名字/类型的名子/主键的值
{
"field":"value",
"field":"value",
.........
}
如果要新增的这条记录在ES中不存在,下面的命令就是一个新增操作。
PUT /schools/student/1
{
"name":"scott"
}
如果要新增的这条记录在ES中存在,下面的命令就是一个更新操作。
PUT /schools/student/1
{
"name":"scott"
}
POST /索引的名字/类型的名子/主键的值
{
"field":"value",
"field":"value",
.........
}
POST 新增数据的时候,可以带id 也可以不带id。如果不带id的话,会自动生成id。如果带了id。这个id在ES中存在当前的POST操作就是一个更新的操作。如果id不存在则是一个新增的操作。
POST PUT 都可以用作新增可以用作修改。 POST 如果不指定id,会自动生成id。PUT必须指定id。
POST PUT 所带的ID相同,则执行更新操作。
乐观锁
ES中有个乐观锁的的概念
seq_no: 表示版本号。当作乐观锁来使用。
PUT /school/student/1?if_seq_no=4&if_primary_term=1
{
"name":"张三",
"age":30
}
2.3 查询记录
查询记录
GET /school/student/1
2.4 更新文档
POST /schools/student/1/_update
{
"doc":{
"name":"ford"
}
}
或者
POST /schools/student/1
{
"name":"ford"
}
或者
PUT /schools/student/1
{
"name":"ford"
}
POST 带_update进行更新的时候,会比较原来的值,如果值没有变化则不更新。
使用_update更新 doc关键字不能缺少,_update只更新指定字段的值,其他的字段不会删除。而其他的更新方式,不赋值的字段会直接删除。如下所示:
更新记录,给记录添加age属性
PUT /schools/student/1
{
"name":"ford",
"age":20
}
使用PUT命令或者是POST不带_update更新
PUT /schools/student/1
{
"name":"ford"
}
在查询此条记录
GET /schools/student/1
会发现age属性没有了。如果使用POST _update更新,则age属性还存在。
2.5 删除文档
delete /索引名/类型/_id
查询索引中的所有记录
GET /索引名/_search
{
"query": {
"match_all": {}
}
}
2.6 删除整个索引
delete /schools
2.7 映射操作
索引创建之后,等于有了关系型数据库中的database。
Elasticsearch7.x取消了索引type类型的设置。不允许指定类型,默认为_doc,但字段仍然是有的,我们需要设置字段的约束信息,叫做字段映射(mapping)Index-->DataBase
Type(_doc)-->Table
Document-->Row
字段的约束包括但不限于:
字段的数据类型
是否要存储
是否要索引
分词器
2.7.1 查看映射
GET /school/_mapping
三 Elasticsearch的高级应用
3.1 match查询 全文检索
GET /company-index/_search
{
"query": {
"match": {
"job": "Java软件工程师"
}
}
}
3.2 match_phrase查询 短语查询 不用分词
GET /company-index/_search
{
"query": {
"match_phrase": {
"job": "Java软件工程师"
}
}
}
3.2 multi_match查询
GET /company-index/_search
{
"query": {
"multi_match": {
"query": "李四",
"fields": ["name","job"]
}
}
}
3.3 bool 复合查选
must
文档必须匹配这些条件才能被包含进来
must_not
文档必须不匹配这些条件才能被包含进来
should
如果文档满足should内的条件,将为该文档增加_score,否则无任何影响
filter
使用过滤模式来进行查询
term
精确查询,全文检索使用match,其他非text字段使用term。
GET /company-index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"job": "软件工程师"
}
}
],
"must_not": [
{"match": {
"name": "李四"
}}
],
"should": [
{"range": {
"payment": {
"gte": 9000,
"lte": 20000
}
}}
],
"filter": {
"term":{
"_id":1
}
}
}
}
}