1. 概述
1.1 基于数据库查询的问题
- 使用数据库查询信息
- 信息过多,数据库查询会全表扫描,性能低
- 关系型数据库提供的查询,功能太弱,使用体验不好
1.2 倒排索引
- 将各个文档中的内容进行分词,形成词条,然后记录词条和数据的唯一标识(id)的对应关系,形成的产物。
1.3 ES概念详解
- ElasticSearch是一个基于Lucene的搜索服务器,搜索即为查询
- 是一个分布式、高扩展、高实时的搜索与数据分析引擎
- 基于RESTful web接口
- ElasticSearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎
- 官网:https://www.elastic.co/
- Lucene
- 一个开源的全文检索引擎工具包
- solr
- 一个独立的企业级搜索应用服务器,它对外提供类似与Web-service的API接口
- 一个独立的企业级搜索应用服务器,它对外提供类似与Web-service的API接口
- MySQL有事务性,而ElasticSearch没有事务性,所以你删了的数据是无法恢复的
- ElasticSearch没有物理外键这个特性,如果你的数据强一致性要求比较高,建议慎用
- ElasticSearch和MySQL分工不同,MySQL负责存储数据,ElasticSearch负责搜索数据
2. 相关软件安装
2.1 ElasticSearch
- 上传ElasticSearch安装包
# 打开sftp窗口
alt+p
# 上传es安装包
put e:/software/elasticsearch-7.4.0-linux-x86_64.tar.gz
- 执行解压操作 ,如下
# 将elasticsearch-7.4.0-linux-x86_64.tar.gz解压到opt文件夹下. -C 大写
tar -zxvf elasticsearch-7.4.0-linux-x86_64.tar.gz -C /opt
- 创建普通用户
- 因为安全问题,Elasticsearch 不允许root用户直接运行,所以要创建新用户,在root用户中创建新用户,执行如下命令:
# 新增itheima用户
useradd itheima
# 为itheima用户设置密码
passwd itheima
- 为新用户授权,如下
chown -R itheima:itheima /opt/elasticsearch-7.4.0 #文件夹所有者
- 修改elasticsearch.yml文件
vi /opt/elasticsearch-7.4.0/config/elasticsearch.yml
# Elasticsearch Configuration
cluster.name: my-application
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
cluster.initial_master_nodes: ["node-1"]
- 详解
- cluster.name:配置elasticsearch的集群名称,默认是elasticsearch。建议修改成一个有意义的名称
- node.name:节点名,elasticsearch会默认随机指定一个名字,建议指定一个有意义的名称,方便管理
- network.host:设置为0.0.0.0允许外网访问
- http.port:Elasticsearch的http访问端口
- cluster.initial_master_nodes:初始化新的集群时需要此配置来选举master
- 修改配置文件
- 新创建的itheima用户最大可创建文件数太小,最大虚拟内存太小,切换到root用户,编辑下列配置文件, 添加类似如下内容
# 切换到root用户
su root
#1. 最大可创建文件数太小
vi /etc/security/limits.conf
# 在文件末尾中增加下面内容
itheima soft nofile 65536
itheima hard nofile 65536
vi /etc/security/limits.d/20-nproc.conf
# 在文件末尾中增加下面内容
itheima soft nofile 65536
itheima hard nofile 65536
* hard nproc 4096
# 注:* 代表Linux所有用户名称
#2. 最大虚拟内存太小
vi /etc/sysctl.conf
# 在文件中增加下面内容
vm.max_map_count=655360
# 重新加载,输入下面命令:
sysctl -p
- 启动elasticsearch
su itheima # 切换到itheima用户启动
cd /opt/elasticsearch-7.4.0/bin
./elasticsearch #启动
- 通过上图我们可以看到elasticsearch已经成功启动
2.2 kibana
- 什么是Kibana
- Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana,可以通过各种图表进行高级数据分析及展示。
- Kibana让海量数据更容易理解。它操作简单,基于浏览器的用户界面可以快速创建仪表板(dashboard)实时显示Elasticsearch查询动态。
- 上传kibana
- CRT中克隆一个窗口,上传Kibana
put E:\software\kibana-7.4.0-linux-x86_64.tar.gz
- 解压kibana
tar -xzf kibana-7.4.0-linux-x86_64.tar.gz -C /opt
- 解压到当前目录(/opt)下
- 修改kibana配置
vi /opt/kibana-7.4.0-linux-x86_64/config/kibana.yml
server.port: 5601 server.host: "0.0.0.0" server.name: "kibana-itcast" elasticsearch.hosts: ["http://127.0.0.1:9200"] elasticsearch.requestTimeout: 99999
- 详解
- server.port:http访问端口
- server.host:ip地址,0.0.0.0表示可远程访问
- server.name:kibana服务名
- elasticsearch.hosts:elasticsearch地址
- elasticsearch.requestTimeout:请求elasticsearch超时时间,默认为30000,此处可根据情况设置
- 详解
- 启动kibana
- 由于kibana不建议使用root用户启动,如果用root启动,需要加–allow-root参数
# 切换到kibana的bin目录 cd /opt/kibana-7.4.0-linux-x86_64/bin # 启动 ./kibana --allow-root
- 如上图,启动成功。
- 访问kibana
- 浏览器输入http://ip地址:5601/
- 看到界面,说明Kibanan已成功安装。
- 组件详解
- Discover:可视化查询分析器
- Visualize:统计分析图表
- Dashboard:自定义主面板(添加图表)
- Timelion:Timelion是一个kibana时间序列展示组件(暂时不用)
- Dev Tools:Console控制台(同CURL/POSTER,操作ES代码工具,代码提示,很方便)
- Management:管理索引库(index)、已保存的搜索和可视化结果(save objects)、设置 kibana 服务器属性。
3. 脚本操作ES
3.1 ES核心概念
- 索引(index)
- ElasticSearch存储数据的地方,可以理解成关系型数据库中的数据库概念
- 映射(mapping)
- mapping定义了每个字段的类型、字段所使用的分词器等,相当于关系型数据库中的表结构
- 文档(document)
- ElasticSearch中的最小数据单元,常以json格式显示,一个document相当于关系型数据库中的一行数据
- 倒排索引
- 一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,对应一个包含它的文档id列表
- 类型(type)
- 一种type就像一类表,如用户表,角色表等,在ElasticSearch7_X默认type为_doc
- ES 5.x中一个index可以有多种type
- ES 6.x中一个index只能有一种type
- ES 7.x以后,将逐步移除type这个概念,现在的操作已经不再使用,默认_doc
- 一种type就像一类表,如用户表,角色表等,在ElasticSearch7_X默认type为_doc
- RESTful风格
- REST(Representational State Transfer),表述性状态转移,是一组架构约束条件和原则,满足这些约束条件和原则的应用程序或设计就是RESTful。就是一种定义接口的规范
- 基于HTTP
- 可以使用XML格式定义或JSON格式定义
- 每一个URI代表一种资源
- 客户端使用GET、POST、PUT、DELETE 4个表示操作方式的动词对服务端资源进行操作
- GET:用来获取资源
- POST:用来新建资源(也可以用于更新资源)
- PUT:用来更新资源
- DELETE:用来删除资源
3.2 操作索引
- 添加索引
PUT http://ip:端口/索引名称
- 查询索引
GET http://ip:端口/索引名称
:查询单个索引信息GET http://ip:端口/索引名称1,索引名称2...
:查询多个索引信息GET http://ip:端口/_all
:查询所有索引信息
- 删除索引
DELETE http://ip:端口/索引名称
- 关闭索引
POST http://ip:端口/索引名称/_close
- 打开索引
POST http://ip:端口/索引名称/_open
3.3 操作映射
3.3.1 数据类型
- 简单数据类型
- 复杂数据类型
3.3.2 简单数据类型
- 字符串
- text:会分词,不支持聚合
- keyword:不会分词,将全部内容作为一个词条,支持聚合
- 数值
- 布尔
- boolean
- 二进制
- binary
- 范围类型
- integer_range,float_range,long_range,double_range,date_range
- 日期
- date
3.3.3 复杂数据类型
- 数组:[]
- Nested:nested(for arrays of JSON objects 数组类型的JSON对象)
- 对象:{}
- Object:object(for single JSON objects 单个JSON对象)
3.3.4 操作
- 添加映射
PUT /person/_mapping { "properties":{ "name":{ "type":"text" }, "age":{ "type":"integer" } } }
- 创建索引并添加映射
PUT /person/ { "mappings":{ "properties":{ "name":{ "type":"text" }, "age":{ "type":"integer" } } } }
- 查询映射
GET /person/_mapping ``
- 添加字段
PUT /person/_mapping { "properties":{ "address":{ "type":"text" } } }
3.4 操作文档
- 添加文档,指定id
PUT person/_doc/1 { "name":"张三", "age":20, "address":"北京市海淀区" }
- 添加文档,不指定id
POST person/_doc { "name":"张三", "age":20, "address":"北京市海淀区" }
- 查询指定id的文档
GET person/_doc/1
- 查询所有文档
GET person/_search
- 删除指定id文档
DELETE person/_doc/1
- 查询结果说明
3.5 查询文档-使用IK分词器
3.5.1 分词器
- 分词器(Analyzer)
- 将一段文本,按照一定的逻辑,分析成多个词语的一种工具
- ElasticSearch内置分词器
- Standard Analyzer
- 默认分词器,按词切分,小写处理
- Simple Analyzer
- 按照非字母切分(符号被过滤),小写处理
- Stop Analyzer
- 小写处理,停用词过滤(the,a,is)
- Whitespace Analyzer
- 按照空格切分,不转小写
- Keyword Analyzer
- 不分词,直接将输入当作输出
- Patter Analyzer
- 正则表达式,默认\W+(非字符分割)
- Language
- 提供了30多种常见语言的分词器
- Standard Analyzer
- ElasticSearch内置分词器对中文很不友好,处理方式为:一个字一个词
3.5.2 IK分词器
- IKAnalyzer是一个开源的,基于Java语言开发的轻量级的中文分词工具包
- 是一个基于Maven构建的项目
- 具有60万字/秒的高速处理能力
- 支持用户词典扩展定义
- 下载地址:https://github.com/medcl/elasticsearch-analysis-ik/archive/v7.4.0.zip
3.5.3 IK分词器安装
- Elasticsearch 要使用 ik,就要先构建 ik 的 jar包,这里要用到 maven 包管理工具,而 maven 需要java 环境,而 Elasticsearch 内置了jdk, 所以可以将JAVA_HOME设置为Elasticsearch 内置的jdk
- 设置JAVA_HOME
vi /etc/profile # 在profile文件末尾添加 #java environment export JAVA_HOME=/opt/elasticsearch-7.4.0/jdk export PATH=$PATH:${JAVA_HOME}/bin # 保存退出后,重新加载profile source /etc/profile
- 下载maven安装包
wget http://mirror.cc.columbia.edu/pub/software/apache/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.tar.gz
- 解压maven安装包
tar xzf apache-maven-3.1.1-bin.tar.gz
- 设置软连接
ln -s apache-maven-3.1.1 maven
- 设置path
- 打开文件
vim /etc/profile.d/maven.sh
- 将下面的内容复制到文件,保存
export MAVEN_HOME=/opt/maven export PATH=${MAVEN_HOME}/bin:${PATH}
- 设置好Maven的路径之后,需要运行下面的命令使其生效
source /etc/profile.d/maven.sh
- 打开文件
- 验证maven是否安装成功
mvn -v
- 下载IK
wget https://github.com/medcl/elasticsearch-analysis-ik/archive/v7.4.0.zip
- 解压IK
yum install zip yum install unzip unzip v7.4.0.zip
- 编译jar包
# 切换到 elasticsearch-analysis-ik-7.4.0目录 cd elasticsearch-analysis-ik-7.4.0/ #打包 mvn package
- jar包移动
- package执行完毕后会在当前目录下生成target/releases目录,将其中的elasticsearch-analysis-ik-7.4.0.zip。拷贝到elasticsearch目录下的新建的目录plugins/analysis-ik,并解压
#切换目录 cd /opt/elasticsearch-7.4.0/plugins/ #新建目录 mkdir analysis-ik cd analysis-ik #执行拷贝 cp -R /opt/elasticsearch-analysis-ik-7.4.0/target/releases/elasticsearch-analysis-ik-7.4.0.zip /opt/elasticsearch-7.4.0/plugins/analysis-ik #执行解压 unzip /opt/elasticsearch-7.4.0/plugins/analysis-ik/elasticsearch-analysis-ik-7.4.0.zip
- 拷贝词典
- 将elasticsearch-analysis-ik-7.4.0目录下的config目录中的所有文件 拷贝到elasticsearch的config目录
cp -R /opt/elasticsearch-analysis-ik-7.4.0/config/* /opt/elasticsearch-7.4.0/config
要重启ElasticSearch
3.5.4 IK分词器使用
- IK分词器有两种分词模式
- ik_max_word 和 ik_smart
- ik_max_work
- 会将文本做最细粒度的拆分,比如会将“乒乓球明年总冠军”拆分为“乒乓球、乒乓、球、明年、总冠军、冠军。
GET /_analyze { "analyzer": "ik_max_word", "text": "乒乓球明年总冠军" }
- ik_smart
- 会做最粗粒度的拆分,比如会将“乒乓球明年总冠军”拆分为乒乓球、明年、总冠军。
GET /_analyze { "analyzer": "ik_smart", "text": "乒乓球明年总冠军" }
3.5.5 查询文档
- 词条查询(term)
- 词条查询不会分析查询条件,只有当词条和查询字符串完全匹配时才匹配搜索
#查询person中匹配到“张三”两个字的词条 GET person/_search { "query":{ "term":{ "name":{ "value":"张三" } } } }
- 全文查询(match)
- 全文查询会分析查询条件,先将查询条件进行分词,然后查询,求并集
#将北京分词,再查询全部,最后求并集 GET person/_search { "query":{ "match":{ "address":"北京" } } }
4. JavaAPI操作
4.1 SpringBoot整合ES
- 搭建SpringBoot工程
- 引入ElasticSearch相关坐标
<!--引入es的坐标-->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.4.0</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.4.0</version>
</dependency>
- 测试
//ElasticSearchConfig
@Configuration
@ConfigurationProperties(prefix="elasticsearch")
public class ElasticSearchConfig {
private String host;
private int port;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Bean
public RestHighLevelClient client(){
return new RestHighLevelClient(RestClient.builder(
new HttpHost(host,port,"http")
));
}
}
注意
- 使用@Autowired注入RestHighLevelClient 如果报红线,则是因为配置类所在的包和测试类所在的包,包名不一致造成的
//ElasticsearchDay01ApplicationTests
@SpringBootTest
class ElasticsearchDay01ApplicationTests {
@Autowired
RestHighLevelClient client;
//测试
@Test
void contextLoads() {
System.out.println(client);
}
}
4.2 操作索引
- 创建索引
/**
* 添加索引
* @throws IOException
*/
@Test
public void addIndex() throws IOException {
//1.使用client获取操作索引对象
IndicesClient indices = client.indices();
//2.具体操作获取返回值
//2.1 设置索引名称
CreateIndexRequest createIndexRequest=new CreateIndexRequest("itheima");
CreateIndexResponse createIndexResponse = indices.create(createIndexRequest, RequestOptions.DEFAULT);
//3.根据返回值判断结果
System.out.println(createIndexResponse.isAcknowledged());
}
//添加索引,并添加映射
@Test
public void addIndexAndMapping() throws IOException {
//1.使用client获取操作索引对象
IndicesClient indices = client.indices();
//2.具体操作获取返回值
//2.具体操作,获取返回值
CreateIndexRequest createIndexRequest = new CreateIndexRequest("itcast");
//2.1 设置mappings
String mapping = "{\n" +
" \"properties\" : {\n" +
" \"address\" : {\n" +
" \"type\" : \"text\",\n" +
" \"analyzer\" : \"ik_max_word\"\n" +
" },\n" +
" \"age\" : {\n" +
" \"type\" : \"long\"\n" +
"