docker搭建es环境
1.部署单点es
1.1创建网络(为了让ElasticSearch和kibana容器互联)
docker network create es-net
1.2拉取镜像
#这里注意和后面拉取的看kibana镜像的版本保持一致
docker pull elasticsearch 7.12.1
1.3创建并运行容器
ddocker run -d \
--name es \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-e "discovery.type=single-node" \
-v es-data:/usr/share/elasticsearch/data \
-v es-plugins:/usr/share/elasticsearch/plugins \
--privileged \
--network es-net \
-p 9200:9200 \
-p 9300:9300 \
elasticsearch:7.12.1
#命令解释:
#-e "cluster.name=es-docker-cluster":设置集群名称
#-e "http.host=0.0.0.0":监听的地址,可以外网访问
#-e "ES_JAVA_OPTS=-Xms512m -Xmx512m":内存大小
#-e "discovery.type=single-node":非集群模式,单点部署
#-v es-data:/usr/share/elasticsearch/data:挂载逻辑卷,绑定es的数据目录
#-v es-logs:/usr/share/elasticsearch/logs:挂载逻辑卷,绑定es的日志目录
#-v es-plugins:/usr/share/elasticsearch/plugins:挂载逻辑卷,绑定es的插件目录
#--privileged:授予逻辑卷访问权
#--network es-net :加入一个名为es-net的网络中
#-p 9200:9200:端口映射配置
1.4部署成功后访问9200端口查看运行状态
2.部署kibana
2.1拉取kibana镜像
#注意这里的版本和es版本保持一致
docker pull kibana:7.12.1
2.2创建并运行容器
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net -p 5601:5601 kibana:7.12.1 \
#--network es-net :加入一个名为es-net的网络中,与elasticsearch在同一个网络中
#-e ELASTICSEARCH_HOSTS=http://es:9200":设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch
#-p 5601:5601:端口映射配置
docker logs -f kibana #查看kibana的运行状态(日志)
3.安装ik分词器
3.1在github上下载ik分词器
- 地址:https://github.com/medcl/elasticsearch-analysis-ik
- 找到对应版本下载zip文件即可,然后用docker volume inspect es-plugins命令查看es的数据卷挂载地址。
- 然后将ik分词器解压上传到这个目录中即可。
4.分词器拓展词和停用词
- 在分词器所在的目录中找到config/IKAnalyzer.cfg.xml文件
- 修改IKAnalyzer.cfg.xml文件
ik分词器会去读这两个文件
- 新建这两个文件,在ext.dic中加入需要扩展的字典,在stopword.dic中加入需要屏蔽的词,ik分词器会自动去读取这两个文件
- 重启es
docker restart es
-
ik分词器的模式
- ik_smart 智能切分,粗粒度
- ik_max_word 细粒度切分
-
创建索引库
这里注意自己使用代码创建索引库时字段名使用小驼峰有时会自动转为下划线模式,但是你插入数据时没有匹配到索引库的字段索引库会自动创建字段去接收你插入的数据,但是插入数据时字段名不会改变,是小驼峰就是小驼峰,所以一定要注意索引库里面字段的类型,到底是keyWord还是text!!!
#创建索引库
PUT /hotel
{
"mappings": {
"properties": {
"id":{
"type":"keyword"
},
"name":{
"type":"text", #类型为text表示该字段需要分词
"analyzer": "ik_max_word", #指定分词器为ik_max_word
#"index": true #表示该字段可以用于搜索,默认为true,可以不写
"copy_to": "all" #可以同时根据多个字段搜
},
"address":{
"type":"keyword", #类型为keyword表示该字段不分词,因此不用指定分词工具。
"index": false #表示该字段不能用于搜索
},
"price":{
"type":"integer"
},
"score":{
"type":"integer"
},
"brand":{
"type":"keyword",
"copy_to": "all"
},
"city":{
"type":"keyword"
},
"star_name":{
"type":"keyword"
},
"business":{
"type":"keyword",
"copy_to": "all"
},
"location":{
"type": "geo_point" #地理坐标,拼接经纬度
},
"pic":{
"type":"keyword",
"index": false
},
"all":{
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
#查询es中全部的索引库
GET _cat/indices
#查看索引库结构命令,index对应你自己的索引库名
GET /index/_mapping
4.查询语法
4.1全文检索查询(匹配text类型字段)
#查询所有 默认只展示前10条数据,hotel为索引库名
GET /hotel/_search
{
"query": {
"match_all": {}
}
}
#全文检索 match查询 all索引库中对应的字段
GET /hotel/_search
{
"query": {
"match": {
"all": "如家"
}
}
}
#multil_match查询 可以匹配多个字段查询
GET /hotel/_search
{
"query": {
"multi_match": {
"query": "外滩如家",
"fields": ["brand","name","business"]
}
}
}
4.2精确查询(匹配除分词以外的字段,如keyword、数值、日期、boolean等的字段)
#term:根据词条精确值查询
GET /hotel/_search
{
"query": {
"term": {
"city": {
"value": "北京"
}
}
}
}
#range:根据值的范围查询
#gte:>= ; lte:<=
GET /hotel/_search
{
"query": {
"range": {
"price": {
"gte": 200,
"lte": 300
}
}
}
}
4.3地理查询(经纬度)
#geo_bounding_box:查询geo_point值在某个矩形范围的所有数据
#geo_distance:查询到指定中心点小于某个距离的所有数据
#location为索引库中存放地理位置的字段,值改为你自己所在的经纬度位置就能实现查看附近的人
GET /hotel/_search
{
"query": {
"geo_distance":{
"distance": "15km",
"location": "39.914539, 116.413392"
}
}
}
4.4复合查询
# function scroce query,可以修改文档的相关算分,根据新得到的算分排序,算分越大越靠前
# "query": { "match": {"all": "外滩"}}:先根据原始查询条件查询数据
# "filter": {"term": { "brand": "如家" } }:定义过滤条件,符合这个条件的会被重新算分
# "weight": 10 给一个常量值,重新得到的分数默认与这个值相乘
# "boost_mode": "sum" :加权模式,这里表示相加,默认为乘
#这样操作后搜索出来的如家酒店就排在最前面
#function scroce query
GET /hotel/_search
{
"query": {
"function_score": {
"query": {
"match": {
"all": "外滩"
}
},
"functions": [
{
"filter": {
"term": {
"brand": "如家"
}
},
"weight": 10
}
],
"boost_mode": "sum"
}
}
}
# Boolean query:是一个或多个查询子句的组合
# 组合方式:
# must:必须匹配每个子查询,类似“与”
# should:选择性匹配子查询,类似“或”
# must_not:必须不匹配,不参与算分,类似“非”
# filter:必须匹配,不参与算分
# Boolean query
# 搜索名字包含如家,价格不高于40,在坐标31.21,121.5周围10km范围内的酒店
GET /hotel/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "如家"
}
}
],
"must_not": [
{
"range": {
"price": {
"gt": 400
}
}
}
],
"filter": [
{
"geo_distance": {
"distance": "10km",
"location": {
"lat": 31.21,
"lon": 121.5
}
}
}
]
}
}
}
5.搜索结果处理
5.1排序(排序后原来的算分不起作用)
# sort排序 按酒店评分的降序,价格降序排序
GET /hotel/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"score": "desc"
},
{
"price": "asc"
}
]
}
# 找到距离某个坐标周围的酒店,按距离升序排序
GET /hotel/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_geo_distance": {
"location": {
"lat": 31.03,
"lon": 121.61
},
"order": "asc",
"unit": "km"
}
}
]
}
5.1分页
# 分页
# from:从第几条数据开始
# size:展示多少条数据,默认为10条数据
# from=(page-1)*size 分页公式
#最多查10000条数据
GET /hotel/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"price": {
"order": "asc"
}
}
],
"from": 0,
"size": 20
}
5.2高亮
# 高亮(在搜索结果中对搜素出来的关键字突出显示)
# 默认情况下,es搜索字段必须和高亮字段一致 即"require_field_match": "true"
# "require_field_match": "false"表示查询字段可以与高亮字段不一致
GET /hotel/_search
{
"query": {
"match": {
"all": "如家"
}
},
"highlight": {
"fields": {
"name": {
"require_field_match": "false"
}
}
}
}
注意:高亮显示不改变原来的数据,需要自行对高亮结果数据进行替换!
此篇文章通过对黑马课程的es学习所写,大家可以多多支持黑马的课程,讲的挺不错的!