一、概述
搜索在现代日常生活场景中都非常常见,如百度、京东、天猫等等。数据量都是庞大的,所以直接基于数据库搜索必定不是他们的首选,在这些场景下,要完成数据的高效搜索,都会基于搜索引擎实现。
而对于搜索实现来说,市面上常见三种技术:Lucene、Solr、ElasticSearch。Lucene严格意义来讲,并不能称为搜索引擎,其本身是一套类库,需要开发人员根据其内部API完成具体功能实现。而Solr和ElasticSearch都是基于Lucene进行了封装,他俩可以称为搜索引擎。但由于实现细节的不同,所以ElasticSearch是目前搜索引擎的首选。
ElasticSearch是一个开源的、支持分布式的、能够进行近实时搜索和分析、能够处理PB级数据量的搜索引擎。目前有很多平台和工作场景会涉及到对ElasticSearch的使用
- 维基百科数据搜索
- Github数据搜索
- 电商平台商品搜索
- 数据分析和挖掘
二、ElasticSearch和MySQL的区别
Lucene 算法 倒排索引 先分词 建立原来数据的关系
- Mysql数据操作具备事务性,而ElasticSearch没有
- MySQL支持外键,而ElasticSearch不支持
- Mysql采用B+树索引,而ElasticSearch采用倒排索引
三、ES安装
采用docker-componse工具安装
1、下载docker-compose
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/dockercompose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
2、授权
sudo chmod +x /usr/local/bin/docker-compose
3、创建链接
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
4、检查安装是否完成
docker-compose -v
5、相关命令
--查看版本
docker-compose version
--根据yml创建
service docker-compose up -d
–-指定yaml
docker-compose up -f xxx.yaml
--查看images
docker-compose images
--停止/启动service
docker-compose stop/start
--销毁
docker-compose down
6、ES安装
--创建两个目录
mkdir -p /usr/local/elk/{elasticsearch/data,elasticsearch/plugins}
--授权
chmod 777 /usr/local/elk/elasticsearch/data
vim docker-compose.yml
version: '3'
services:
elasticsearch:
image: elasticsearch:7.10.1 #镜像
container_name: elasticsearch #定义容器名称
restart: always #开机启动,失败也会一直重启
environment:
- "cluster.name=elasticsearch" #设置集群名称为elasticsearch
- "discovery.type=single-node" #以单一节点模式启动
- "ES_JAVA_OPTS=-Xms512m -Xmx1024m" #设置使用jvm内存大小 生成环境建议最低3g以上
volumes:
- /usr/local/elk/elasticsearch/plugins:/usr/share/elasticsearch/plugins #
插件文件挂载
- /usr/local/elk/elasticsearch/data:/usr/share/elasticsearch/data #数据文件
挂载
ports:
- 9200:9200
kibana: #图形化操作工具
image: kibana:7.10.1
container_name: elk_kibana
restart: always
depends_on:
- elasticsearch #kibana在elasticsearch启动之后再启动
environment:
- ELASTICSEARCH_URL=http://elasticsearch:9200 #设置访问elasticsearch的地址
ports:
- 5601:5601
docker-componse up -d
http://ip:5601/
四、 ElasticSearch核心概念介绍
ES在使用时,会涉及到五个核心概念:索引(Index)、映射(Mapping)、文档(Document)、倒排索引。
注:在老版本ElasticSearch中还有一个概念Type,用于进行数据分类,但是在ES7开始已经将Type移除
4.1 索引(index)
索引相当于关系型数据库中的一张表,一个index包含若干document,通过Index代表一类类似的或者相同的document。
4.1.1 添加索引
-- PUT 索引名称
PUT person
4.1.2 查询索引
-- 查询单个索引 GET 索引名称
GET person
-- 查询多个索引信息 GET 索引名称,索引名称
GET person,person1
-- 查询所有索引信息
GET _all
4.1.3 删除索引
-- 删除索引 DELETE 索引名称
DELETE person1
4.2 映射(Mapping)
域(Field)相当于数据表中的字段列,当有了索引之后,需要在索引中设置域的相关信息如:名称,
类型等。这个过程称为:映射(Mapping)。相当于关系型数据库中表的设计。
4.2.1 数据类型
字符串
- text:会进行分词,如华为手机,会分成:华为,手机。 被分出来的每一个词,称为term(词
条) - keyword:不会进行分词,如华为手机,只有一个词条,即华为手机。
数值
- long:带符号64位整数
- integer:带符号32位整数
- short:带符号16位整数
- byte:带符号8位整数
- double:双精度64位浮点数
- float:单精度32位浮点数
- half_float:半精度16位浮点数
布尔
- binary
日期
- date
范围类型
-
integer_range
-
float_range
-
long_range
-
double_range
-
date_range
数组
- 对象
4.2.2 添加映射
- 对于映射,只能进行字段添加,不能对字段进行修改或删除,如有需要,则重新创建映射
添加映射(添加/修改字段)
-- 为已存在的索引库添加映射
PUT person/_mapping
{
"properties":{
"name":{
"type":"text"
},
"age":{
"type":"integer"
}
}
}
-- 创建索引+映射
PUT person
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
}
}
}
}
查看映射
--查看索引映射信息
GET person/_mapping
4.3 文档(Document)
- ES中最小的数据单元,代表索引中的一条数据,通常是使用json的数据格式表示的
4.3.1 添加文档(添加一行数据)
- 手动设置id
POST person/_doc/1
{
"name":"张三",
"age":18,
"address":"北京"
}
- 自动生成id
POST person/_doc
{
"name":"张三",
"age":18,
"address":"北京"
}
4.3.2 查询文档
- 根据id查询文档
GET person/_doc/1
- 查询所有文档
GET person/_search
4.3.3 修改文档
PUT person/_doc/1
{
"name": "张三丰",
"age": 180,
"address": "武当山"
}
4.3.4 删除文档
--DELETE 索引名称/_doc/文档id
DELETE person/_doc/1
五、ik分词器及搜索支持
5.1 分词器
- 默认分词器支持英文及空格
POST _analyze
{
"text": "I love beijing"
}
POST _analyze
{
"text": "Ilovebeijing"
}
POST _analyze
{
"text": "我爱北京天安门"
}
- 需安装分词器
- 支持 ik_max_word、 ik_smart 两种分词器
PUT person2
{
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_smart"
},
"age": {
"type": "integer"
},
"address":{
"type":"text",
"analyzer": "ik_max_word"
}
}
}
}
5.2 搜索
- term:搜索内容不进行分词
- match:对搜索内容进行分词,同时搜索:北京、大运河
--term:对搜索内容不进行分词
GET person2/_search
{
"query": {
"term": {
"address": "大运河"
}
}
}
#match:对搜索内容进行分词,同时搜索:北京、大运河
GET person2/_search
{
"query": {
"match": {
"address": "北京大运河"
}
}
}