目录
创建es容器,es和kinaba都有差不多一个g,需要等待一会
什么是ElasticSearch?
一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能。ElasticSearch也是ElasticStack(esk)的核心,包括负责数据抓取的Logstash和Beats,负责储存、计算、搜索数据的ElasticSearch,还有负责数据可视化的Kibana。
ElasticSearch核心是Lucene,Lucene是一个基于java语言的搜索引擎类库,提供了搜索引擎的核心API,由DougCutting于1999年研发,是Apache公司的顶级项目,具有易扩展,高性能的特性,但是不支持分布式,难学习并且只支持java开发。于是2004年的时候大神Shay Banon根据Lucene开发了Compass,据说当时只是为了给老婆写一个搜索引擎找食谱学做菜,所以当时也不支持分布式开发,后面作者意识到这一点在2010年的时候重写了Compass并改名为ElasticSearch(官方网址免费且开放的搜索:Elasticsearch、ELK 和 Kibana 的开发者 | Elastic),支持分布式,可水平扩展、提供Restful接口,可以被任何语言调用。当然这几年间也有其他的搜索引擎诞生,在ElasticSearch出现之前用的最多的就是Apache公司的Solr了,但是ElasticSearch出现之后也渐渐成为全球使用最多的搜索引擎工具了,到现在全球的下载次数已经2亿+了。
正向索引和倒排索引
首先了解两个概念,文档和词条,我们把数据库某一张表中的一条数据称为文档,对于文档内容进行分词,就是词条。比如在订单表里有一条数据为华为手机,那么华为手机就是一个文档,华为和手机就是两个词条。
正向索引,我们所熟悉的mysql数据库就是正向索引,基于文档id创建索引,那么在查询词条时必须先找文档,判断是否包含词条,正因为如此,当我们在搜索数据时会去逐一搜索判断,数据量大时根本查不过来。
倒排索引即与正向索引相反,倒排索引对文档内容进行分词,对词条创建索引,并记录哪些文档id包含了这个词条,查询时先根据词条查询到文档id,根据id出现次数进行关联性排序,再通过文档id获取到文档,效率高了太多。
mysql、es对比
两者建表规则对比
# 酒店的mapping
PUT /hotel
{
"mappings": {
"properties": {
"id":{
//id在es中为string,也就是keyword
"type": "keyword"
},
"name":{
//需要分词的字段为text,analyzer为分词器,值为分词方式
"type": "text",
"analyzer": "ik_max_word",
//如果多个字段要用来进行搜索不用一一搜索,es提供了将多个字段拷贝到一个字段,最后搜索这个字段就行
"copy_to": "all"
},
"address":{
"type": "text",
"index": false
},
"price":{
"type": "integer"
},
"score":{
"type": "integer"
},
"brand":{
"type": "keyword",
"copy_to": "all"
},
"city":{
"type": "keyword"
},
"starName":{
"type": "keyword"
},
"business":{
"type": "keyword",
"copy_to": "all"
},
"location":{
//es的坐标以横纵坐标拼接成一个字符串,为geo_point
"type": "geo_point"
},
"pic":{
"type": "keyword",
"index": false
},
"all":{
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
Docker拉取es并创建容器
创建es容器,es和kinaba都有差不多一个g,需要等待一会
//创建网络,让es和操作工具Kinaba互连
docker network create es-net
//拉取镜像
docker pull elasticsearch:7.12.1
//es命令
- `-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`:端口映射配置
//单点部署命令
docker 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
部署好es之后,访问ip:9200出现以下界面就代表成功
创建kinaba(es操作学习工具)容器
//拉取镜像,注意和es版本要一致
docker pull kibana:7.12.1
//kb命令
- `--network es-net` :加入一个名为es-net的网络中,与elasticsearch在同一个网络中
- `-e ELASTICSEARCH_HOSTS=http://es:9200"`:设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch
- `-p 5601:5601`:端口映射配置
kibana部署较慢,可以等待一会
//部署命令
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601 \
kibana:7.12.1
部署好后访问ip:5601
点击左上角面包屑,点击Dex Tools,即可进入DSL语句发送页面
分词器
既然es需要进行分词,那就需要相应的工具分词器,es自带的分词器只能分英文单词,对于中文只能分成一个一个字,自然不适用。
分词器处理中文分词,一般会使用IK分词器。官网:https://github.com/medcl/elasticsearch-analysis-ik
ik分词器包含两种模式:
•ik_smart:最少切分,粗粒度,比如程序员就只分为程序员,意思是检索到词语就不会继续去检索这个词语了
•ik_max_word:最细切分,细粒度,程序员会分为程序员,程序,员
下载好ik分词器后放到/var/lib/docker/volumes/es-plugins/_data(之前数据卷映射的目录)目录下即可使用ik分词
在ik的config文件夹我们可以进行自己的分词配置,因为有些词比如彦祖,奥里给这些分词器肯定是没有的,有些比如你、我、他、啊、嗯这些词参与搜索也没有意义,因此我们可以进行分词扩展和禁用。首先找到IKAnalyzer.cfg.xml这个文件,在里面指定扩展和禁用文件
然后在config目录创建扩展文件,禁用文件已经有了,直接在里面添加就行
添加好了重启es容器就行,docker restart es。
es操作
mapping是对索引库中文档的约束,常见的mapping属性包括:
•type:字段数据类型,常见的简单类型有:
•字符串:text(可分词的文本)、keyword(精确值,例如:品牌、国家、ip地址)
•数值:long、integer、short、byte、double、float、
•布尔:boolean
•日期:date
•对象:object
•index:是否创建索引,默认为true
•analyzer:使用哪种分词器
•properties:该字段的子字段
索引库操作,索引库一旦创建不可修改mapping,但是可以添加字段:
创建索引库:
PUT /索引库名
•查询索引库:
GET /索引库名
•删除索引库:
DELETE /索引库名
•添加字段:
PUT /索引库名/_mappin
eg:
PUT /hotel/_mappin
{
"properties":{
"star":{
"type": "integer"
}
}
}
文档操作:
•创建文档:
POST /索引库名/_doc/文档id
{
json文档
}
•查询文档:
GET /索引库名/_doc/文档id
•删除文档:
DELETE /索引库名/_doc/文档id
•修改文档:
•全量修改:
PUT /索引库名/_doc/文档id
{
json文档
}
•增量修改:
POST /索引库名/_update/文档id
{
"doc": {
字段
}
}