elasticsearch
简介
Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。
无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,
但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单
elasticsearch除了Lucene和全文搜索,我们还可以描述它:
1.分布式的实时文件存储,每个字段都被索引并可被搜索
2.分布式的实时分析搜索引擎
3.可以扩展到上百台服务器,处理PB级结构化或非结构化数据。
1.必须提前安装Java环境
[root@cs ~]# yum install java-1.8.0-openjdk.x86_64 -y
[root@cs ~]# java -version
2.安装
官网地址: https://www.elastic.co/cn/
elasticsearch,kibana,filebeat 必须保持相关软件版本一致
# 安装环境
centos7.9 + elasticsearch-6.8.15
# 下载
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.15.rpm
# 安装,使用yum安装和rpm命令安装都行
# yum install elasticsearch-6.8.15.rpm -y
rpm -ivh elasticsearch-6.8.15.rpm
# 运行
systemctl enable elasticsearch.service # 加入开机启动
# 运行/停止运行/重启/状态
systemctl start/stop/restart/status elasticsearch.service
systemctl is-active elasticsearch.service # 确认es服务是否还活着
# 检查是否启动成功
curl localhost:9200
3.相关文件查看
# rpm -ql elasticsearch
[root@cs tmp]# rpm -qc elasticsearch
/etc/elasticsearch/elasticsearch.yml # es配置文件
/etc/elasticsearch/jvm.options # java虚拟机的配置文件
/etc/elasticsearch/log4j2.properties # es的日志使用的log4j的框架,所以有log4j的配置
/etc/elasticsearch/role_mapping.yml
/etc/elasticsearch/roles.yml
/etc/elasticsearch/users
/etc/elasticsearch/users_roles
/etc/init.d/elasticsearch # init.d启动脚本
/etc/sysconfig/elasticsearch # 一些环境变量,一般不用更改
/usr/lib/sysctl.d/elasticsearch.conf # 环境变量相关
/usr/lib/systemd/system/elasticsearch.service # systemd启动脚本
/var/log/elasticsearch/elasticsearch.log # es的日志文件
/usr/share/elasticsearch/ # es的安装目录
/usr/share/elasticsearch/bin/elasticsearch-plugin # es用来下载插件的
/usr/share/elasticsearch/plugins/ # es的插件目录
4.修改配置文件
# 手动创建个es的数据目录
[root@cs tmp]# mkdir -p /data/elasticsearch_data
[root@cs tmp]# chown -R elasticsearch:elasticsearch /data/elasticsearch_data/
[root@cs tmp]# vim /etc/elasticsearch/elasticsearch.yml
# 更改后的配置文件内容如下
[root@cs tmp]# grep "^[a-Z]" /etc/elasticsearch/elasticsearch.yml
node.name: node-1
# 保存数据和日志的目录
path.data: /data/elasticsearch_data
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true # 锁定内存
# 监听本机的ip,多个ip逗号间隔
network.host: 192.168.189.128,127.0.0.1
# 完事重启服务
[root@cs tmp]# systemctl restart elasticsearch
# 然后观察日志,你会发现,有报错:
[root@cs tmp]# tail -f /var/log/elasticsearch/elasticsearch.log
'''
[1]: memory locking requested for elasticsearch process but memory is not locked
'''
# 报错意思是锁定内存失败,参考官网的解决办法:
[root@cs tmp]# sudo systemctl edit elasticsearch
# 添加下面两行代码
[Service]
LimitMEMLOCK=infinity
[root@cs tmp]# sudo systemctl daemon-reload
[root@cs tmp]# systemctl restart elasticsearch
5.安装es-head 插件-- 小型可视化工具
chrome的应用商店打不开的话,去这个地址
谷歌浏览器添加扩展插件
引擎可视化工具 - kibana安装
1.安装
# 在安装kibana之前,请确保java环境和elasticsearch都已配置并启动成功。
# 安装环境:
elasticsearch-6.8.15 + kibana-6.8.15 + centos7.9
# 下载安装
[root@cs tmp]# wget https://artifacts.elastic.co/downloads/kibana/kibana-6.8.15-x86_64.rpm
[root@cs tmp]# rpm -ivh kibana-6.8.15-x86_64.rpm
# 启动/状态/重启/停止/加入开机自启/取消开机自启
[root@cs tmp]# systemctl start/status/restart/stop/enable/disable kibana
2.相关目录
/etc/kibana/kibana.yml # kibana配置文件
/usr/share/kibana # kibana安装目录
3.修改配置文件
[root@cs tmp]# vim /etc/kibana/kibana.yml
[root@cs tmp]# grep "^[a-Z]" /etc/kibana/kibana.yml
# 监听的ip和端口
server.port: 5601
server.host: "192.168.189.128"
server.name: "10.0.0.200-kibana" # kibana的服务名
elasticsearch.hosts: ["http://192.168.189.128:9200"] # 访问指定es的hosts
# 重启
[root@cs tmp]# systemctl restart kibana
使用kibana操作es
1.简单操作 -- 增删改查
增
# 创建一篇文档 -- 索引/映射类型/文档id
# 首先检查索引是否存在,不存在先创建索引,再创建文档
PUT zhifou/doc/1
{
"name":"顾老二",
"age":30,
"from": "gu",
"desc": "皮肤黑、武器长、性格直",
"tags": ["黑", "长", "直"]
}
删
# 删除指定文档
DELETE zhifou/doc/4
# 删除指定索引
DELETE /zhifou
改
# doc里指定要修改的字段和内容
POST zhifou/doc/1/_update
{
"doc": { # doc里指定
"desc": "皮肤很黄",
"tags": ["很黄","很长", "很直"]
}
}
查
# 1.查询所有索引
GET _cat/indices?v
# 2.查询指定索引内容
GET zhifou/_search
GET zhifou/doc/_search # 指定类型
# 3.查询指定文档内容
GET zhifou/doc/1
2.复杂查询
1.准备数据
PUT zhifou/doc/1
{
"name":"顾老二",
"age":30,
"from": "gu",
"desc": "皮肤黑、武器长、性格直",
"tags": ["黑", "长", "直"]
}
PUT zhifou/doc/2
{
"name":"大娘子",
"age":18,
"from":"sheng",
"desc":"肤白貌美,娇憨可爱",
"tags":["白", "富","美"]
}
PUT zhifou/doc/3
{
"name":"龙套偏房",
"age":22,
"from":"gu",
"desc":"mmp,没怎么看,不知道怎么形容",
"tags":["造数据", "真","难"]
}
PUT zhifou/doc/4
{
"name":"石头",
"age":29,
"from":"gu",
"desc":"粗中有细,狐假虎威",
"tags":["粗", "大","猛"]
}
PUT zhifou/doc/5
{
"name":"魏行首",
"age":25,
"from":"广云台",
"desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!",
"tags":["闭月","羞花"]
}
2.两种查询方式
字符串查询 -- 不推荐使用
# q后边是查询条件
GET zhifou/doc/_search?q=age:18
GET zhifou/_search?q=age:18
结构化查询 - match查询
# 1.match:返回所有匹配的分词。
# 查询条件是一步步构建出来的,将查询条件添加到match中即可,对查询条件进行分词
GET zhifou/doc/_search
{
"query": {
"match": {
"from": "gu"
}
}
}
# 2.match_all:查询全部。
# match_all的值为空,表示没有查询条件,那就是查询全部
GET zhifou/doc/_search
{
"query": {
"match_all": {}
}
}
# 3.match系列之match_phrase(短语查询)
# 使用match的话,中文会被分成一个一个的字,构不成短语查询,没有意义
GET zhifou/doc/_search
{
"query": {
"match_phrase": {
# 字段 : 想要查询的短语
"desc": "仿佛"
}
}
}
# 4.match系列之match_phrase_prefix(最左前缀查询)
# 当你记不住想要查询的完整单词,可以写最前边的几个字母进行查询
GET zhifou/_search
{
"query": {
"match_phrase_prefix": {
# 查询来自前缀为sh的文档
"from": "sh"
}
}
}
# 5.match系列之multi_match(多字段查询)
# 适用多个字段查询一样的条件
GET t3/doc/_search
{
"query": {
"multi_match": {
"query": "beautiful", # 查询条件
"fields": ["title", "desc"] # 查询字段
}
}
}
# 5.1 multi_match甚至可以当做match_phrase和match_phrase_prefix使用,只需要指定type类型即可
# 最左前缀查询
GET t3/doc/_search
{
"query": {
"multi_match": {
"query": "gi",
"fields": ["title"],
"type": "phrase_prefix"
}
}
}
# 短语查询
GET t3/doc/_search
{
"query": {
"multi_match": {
"query": "girl",
"fields": ["title"],
"type": "phrase"
}
}
}
3.排序查询 -- sort
# 升序:asc -- 降序:desc
# 比如我们查询顾府都有哪些人,并根据age字段按照升序降序排列
GET zhifou/doc/_search
{
"query": {
"match": {
"from": "gu"
}
},
"sort": [
{# 排序字段
"age": {
"order": "asc" # 升序
}
}
]
}
4.分页查询 - from/size
# from:从哪开始查 -- size:查几个
GET zhifou/doc/_search
{
"from": 0,
"size": 2
}
5.布尔查询 -- bool
must:与关系,相当于关系型数据库中的and。
should:或关系,相当于关系型数据库中的or。
must_not:非关系,相当于关系型数据库中的not。
filter:过滤条件。
-range:条件筛选范围。
gt:大于,相当于关系型数据库中的>。
gte:大于等于,相当于关系型数据库中的>=。
lt:小于,相当于关系型数据库中的<。
lte:小于等于,相当于关系型数据库中的<=。
基本操作
# 1.must 与 -- 查询from=gu和age=30的文档
GET zhifou/_search
{
"query": {
"bool": {
# 查询关系类型,是个列表里放查询条件
"must": [
{
"match": {
"from": "gu"
}
},
{
"match": {
"age": "30"
}
}
]
}
}
}
# 2.should 或 -- 查询只要是from为gu或者tags为闭月的数据
GET zhifou/doc/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"from": "gu"
}
},
{
"match": {
"tags": "闭月"
}
}
]
}
}
}
# 3. must_not 非 -- 想要查询from既不是gu并且tags也不是可爱,还有age不是18的数据
GET zhifou/doc/_search
{
"query": {
"bool": {
"must_not": [
{
"match": {
"from": "gu"
}
},
{
"match": {
"tags": "可爱"
}
},
{
"match": {
"age": 18
}
}
]
}
}
}
# 4. filter 过滤查询 -- 要查询from为gu,age大于25的数据
# filter最好与must一起使用,因为查询过程中,优先经过filter过滤,如果是should的话,结果会不准确
GET zhifou/doc/_search
{
"query": {
"bool": {
"must": [
{"match": {
"from": "gu"
}}
],
"filter": {
"range": {
# 过滤字段
"age": {
# 过滤范围
"gt": 25
}
}
}
}
}
}
6.结果过滤:_source
# 在所有的结果中,我只需要查看name和age两个属性,其他的不要怎么办
GET zhifou/_search
{
"query": {
"match": {
"from": "gu"
}
},
# 把我们想要看到的数据放到列表中
"_source": ["name","age"]
}
7.高亮查询 :highlight -- 查询条件在结果中高亮显示
# 1.默认高亮显示
GET zhifou/_search
{
"query": {
"match_phrase": {
"name": "石头"
}
},
"highlight": {
"fields": {
# 需要高亮显示查询条件的字段
"name": {},
"tags": {}
}
}
}
# 2.自定义样式高亮显示
GET zhifou/chengyuan/_search
{
"query": {
"match": {
"from": "gu"
}
},
"highlight": {
# 开始标签 -- 可以写样式
"pre_tags": "<b style='color:red'>",
# 结束标签
"post_tags": "</b>",
"fields": {
"from": {}
}
}
}
8.聚合函数 - 分组查询: aggs
注意:聚合函数的使用,一定是先查出结果,然后对结果使用聚合函数做处理
avg:求平均
max:最大值
min:最小值
sum:求和
分组查询
基本操作:
# 1.avg -- 查询from是gu的人的平均年龄
GET zhifou/doc/_search
{
"query": {
"match": {
"from": "gu"
}
},
"aggs": {
# 自定义函数别名
"pingjun": {
# 聚合函数类型 -- 可以替换成其他类型
"avg": {
# 字段
"field": "age"
}
}
},
# 不想看查询数据,只想看聚合函数值
"size": 0
}
# 2.分组查询
# 想要查询所有人的年龄段,并且按照15~20,20~25,25~30分组,并且算出每组的平均年龄
GET zhifou/doc/_search
{
"size": 0,
"query": {
"match_all": {}
},
# 分组
"aggs": {
# 分组别名
"age_group": {
# 分组
"range": {
# 想要分组字段
"field": "age",
# 分组范围列表
"ranges": [
{
"from": 15,
"to": 20
},
{
"from": 20,
"to": 25
},
{
"from": 25,
"to": 30
}
]
},
# 平均值
"aggs": {
"my_avg": {
"avg": {
"field": "age"
}
}
}
}
}
}
3.自定义索引结构: mappings 映射
1.mappings三种映射,具体由dynamic
属性控制
- 动态映射: dynamic:true -- 默认模式
- 静态映射: dynamic:false
- 严格模式: dynamic:strict
动态映射
# 定义了两个字段类型,当添加新字段sex时,也可以使用新字段进行数据查询
# 因为elasticsearch已经为新增的sex建立了映射关系
PUT m1
{
"mappings": {
"doc":{
"dynamic":true, # 默认动态可不写
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
}
}
}
}
}
静态映射
# 定义了两个字段类型,可以添加新字段sex时,但是使用新字段查询不到数据
# 因为elasticsearch并没有为新增的sex建立映射关系
PUT m2
{
"mappings": {
"doc":{
"dynamic":false,
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
}
}
}
}
}
严格模式
# 定义了两个字段类型,添加新字段,报错,只能添加已经定义的字段数据
PUT m3
{
"mappings": {
"doc": {
"dynamic": "strict",
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
}
}
}
}
}
小结:
- 动态映射(dynamic:true):动态添加新的字段(或缺省)。
- 静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现。
- 严格模式(dynamic: strict):如果遇到新的字段,就抛出异常。
2.index -- 定义是否字段创建索引
首先来创建一个mappings
:
PUT m4
{
"mappings": {
"doc": {
"dynamic": false,
"properties": {
"name": {
"type": "text",
"index": true
},
"age": {
"type": "long",
"index": false
}
}
}
}
}
3.settings 设置主 - 复制分片
在创建一个索引的时候,我们可以在settings
中指定分片信息
PUT s1
{
"mappings": {
"doc": {
"properties": {
"name": {
"type": "text"
}
}
}
},
"settings": {
"number_of_replicas": 1,
"number_of_shards": 5
}
}
# number_of_shards是主分片数量(每个索引默认5个主分片)
# number_of_replicas是复制分片,默认一个主分片搭配一个复制分片