ES
1.初识ES面试必备
- 一个基于Lucene的实时的分布式存储的搜索、分析的引擎。
- 基于RESTful接口。
- Java语言开发的。故内置jdk。
- 就是开发中用到的搜索引擎,实际作用为用来做搜索,常见搭配为es搭配redis完成缓存来使用。
- 应用场景
?搜索:海量数据的查询 ?日志数据分析 ?实时数据分析 - 官网
- 既然用作大数据量的搜索分析引擎,其优势在哪儿?
答:倒排索引
即将文档信息进行分词,形成分词后的词条和文档信息id(唯一标识)的对应关系。即为反向索引。 eg:将数据库中的一条记录进行分词后将有这个词的信息和词条进行对应。 如:记录为:
“我是药神”id为1
“我是孙悟空”id为2
倒排索引:
2. 安装和配置
包括es安装。工具postman、kibana、图形化界面head的安装。
2.1es安装
下载后解压缩在指定目录即可,执行bin下的elasticsearch文件即可。window执行批处理,linux执行另一个。 端口:9200 配置:别的端口连接es时跨域。 打开es安装目录下的config下的elasticsearch.yml文件添加
#配置跨域访问 版本高的都会默认配置该项。
http.cors.enabled: true
http.cors.allow-origin: "*"
# ======================== Elasticsearch Configuration =========================
cluster.name: es1 #集群名称
node.name: node-1 #节点名称
network.host: 0.0.0.0 #通信ip
http.port: 9200 # 端口
cluster.initial_master_nodes: ["node-1"] # 用作集群选举
即可。
2.2工具安装
- postman安装:
下载安装打开即可。 https://www.postman.com/ 一款windows软件打开即可 - Kibane的安装:官方推荐
下载后解压执行bin下的批处理命令即可启动,配置文件中es的连接信息为默认,如有修改则变更即可。 https://www.elastic.co/cn/downloads/kibana 端口:5601 使用:访问localhost:5601即可。操作es主要使用界面左边的dev tools来操作es - ES图形化界面head:
head是由js编写的。由于javascript实现运行需要在node.js上,需要先安装nodejs。 安装启动:解压至指定目录即可,进入该目录cmd执行grunt server 或者 npm run start 命令,如果失败则先执行npm install -g grunt-cli 和npm install 命令 端口:9100 访问使用浏览器即可。如localhost:9100
3.核心概念
此处拿常用的mysql数据和es中的概念进行一个对比
Relational DB ‐> Databases ‐> Tables ‐> Rows ‐> Columns
Elasticsearch ‐> index‐> Types ‐> Documents ‐> Fields(mapping中的具体字段)
索引(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
即一个索引库存放一个表
3.ES数据类型
- 简单数据类型
聚合:相当于mysql 中的sum(求和)
text:会分词,不支持聚合
keyword:不会分词,将全部内容作为一个词条,支持聚合
long、integer、short、byte、double、float、half_float半精度、scaled_float这个过一眼即可暂时
-
布尔:boolean -
二进制:binary。基本不用,占用空间。 -
范围类型
integer_range, float_range, long_range, double_range, date_range
- 复杂数据类型
?数组:[ ] Nested: nested (for arrays of JSON objects 数组类型的JSON对象)
?对象:{ } Object: object(for single JSON objects 单个JSON对象)
4.RESTful操作es
此处用postman进行操作,因为poatman相比于kabana是全称操作。而kibana是简化后的操作。
4.1操作索引
?创建索引
创建索引
PUT http://ip:端口/索引名称
?查询
GET http://ip:端口/索引名称 # 查询单个索引信息
GET http://ip:端口/索引名称1,索引名称2... # 查询多个索引信息
GET http://ip:端口/_all # 查询所有索引信息
?删除索引
DELETE http://ip:端口/索引名称
?关闭、打开索引:
POST http://ip:端口/索引名称/_close #close后不能进行读写操作
POST http://ip:端口/索引名称/_open
4.2 操作映射
?创建映射(创建表结构)
对已有的索引添加mapping
PUT http://localhost:9200/demo1_index/_mapping
BODY:
{
"properties":{
"name":{
"type":"keyword"
},
"address":{
"type":"text"
}
}
}
创建索引并添加mapping
PUT http://localhost:9200/demo2_indexname/
BODY:
{
"mappings":{
"properties":{
"name":{
"type":"keyword"
},
"address":{
"type":"text"
}
}
}
}
?为已有mapping添加字段
POST http://localhost:9200/demo1_index/_mapping
BODY:要添加的字段
{
"properties":{
"add":{
"type":"long"
},
"add1":{
"type":"integer"
}
}
}
4.3 操作文档
?添加文档。分指定_id和不指定
1. 添加文档,指定_id
POST http://localhost:9200/demo1_index/_doc/1
BODY:编写json信息
{
"name":"tom",
"age":19,
"address":"北京朝阳北花园",
"id":1
}
2. 添加文档,不指定_id
POST http://localhost:9200/demo1_index/_doc
BODY:编写json信息
{
"name":"lucy",
"age":17,
"address":"北京朝阳陶家湾",
"id":3
}
?查看文档,根据_id
GET http://localhost:9200/demo1_index/_doc/1
?查看所有文档
GET http://localhost:9200/demo1_index/_search
?根据_id删除文档
DELETE http://localhost:9200/demo1_index/_doc/2
5. 分词器
es默认提供的分析器standard对中文很不友好,会将中文拆分成一个一个字 eg:
#使用分词器
GET http://localhost:9200/demo1_index/_analyze
BODY:
{
"analyzer":"standard",#指定分词器类型
"text":"我是你大爷"
}
Reult:
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "是",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "你",
"start_offset": 2,
"end_offset": 3,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "大",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 3
},
{
"token": "爷",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 4
}
]
}
IK分词器
IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包
?是一个基于Maven构建的项目
?具有60万字/秒的高速处理能力
?支持用户词典扩展定义
下载:更改自己的版本即可
https://link.csdn.net/?target=https%3A%2F%2Fgithub.com%2Fmedcl%2Felasticsearch-analysis-ik%2Freleases%2Fdownload%2Fv7.14.0%2Felasticsearch-analysis-ik-7.14.0.zip
或者
https://github.com/medcl/elasticsearch-analysis-ik/releases
安装:将下载好的zip压缩包解压到es安装目录下的plugins目录下,将config中的所有文件复制到es的config中,启动es即可。 看到该信息表示ik分词器添加成功。
ik分词器的使用
IK分词器有两种分词模式:ik_max_word和ik_smart模式。
1、ik_max_word
会将文本做最细粒度的拆分
GET http://localhost:9200/_analyze
BODY:
{
"analyzer":"ik_max_word",
"text":"我是你的机器人女友"
}
Result:
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "是",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 1
},
{
"token": "你",
"start_offset": 2,
"end_offset": 3,
"type": "CN_CHAR",
"position": 2
},
{
"token": "的",
"start_offset": 3,
"end_offset": 4,
"type": "CN_CHAR",
"position": 3
},
{
"token": "机器人",
"start_offset": 4,
"end_offset": 7,
"type": "CN_WORD",
"position": 4
},
{
"token": "机器",
"start_offset": 4,
"end_offset": 6,
"type": "CN_WORD",
"position": 5
},
{
"token": "人",
"start_offset": 6,
"end_offset": 7,
"type": "CN_CHAR",
"position": 6
},
{
"token": "女友",
"start_offset": 7,
"end_offset": 9,
"type": "CN_WORD",
"position": 7
}
]
}
2、ik_smart 会做最粗粒度的拆分
GET http://localhost:9200/_analyze
BODY:
{
"analyzer":"ik_max_word",
"text":"我是你的机器人女友"
}
Result:
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "是",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 1
},
{
"token": "你",
"start_offset": 2,
"end_offset": 3,
"type": "CN_CHAR",
"position": 2
},
{
"token": "的",
"start_offset": 3,
"end_offset": 4,
"type": "CN_CHAR",
"position": 3
},
{
"token": "机器人",
"start_offset": 4,
"end_offset": 7,
"type": "CN_WORD",
"position": 4
},
{
"token": "女友",
"start_offset": 7,
"end_offset": 9,
"type": "CN_WORD",
"position": 5
}
]
}
使用IK分词器-查询文档
?词条查询:term
? 词条查询不会分析查询条件,只有当词条和查询字符串完全匹配时才匹配搜索
?全文查询:match
? 全文查询会分析查询条件,先将查询条件进行分词,然后查询,求并集。
-
数据准备 -
词条查询
GET http://localhost:9200/demo3_indexname/_search
BODY:
{
"query":{
"term":{/*词条查询,根据倒排索引进行匹配*/
"address":{
"value":"北花园"/*会对倒排索引中所有词条匹配,只有完全匹配才可以!!*/
}
}
}
}
Result:
无数据
- 全文查询
GET http://localhost:9200/demo3_indexname/_search
BODY:
{
"query": {
"match": {/*将词进行拆分,然后进行倒排索引,对结果求并集*/
"address":"朝阳花园"
}
}
}
Result:
{
"took": 20,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 1.5843642,
"hits": [
{
"_index": "demo3_indexname",
"_type": "_doc",
"_id": "3",
"_score": 1.5843642,
"_source": {
"name": "lucy",
"age": 20,
"address": "北京朝阳花园",
"id": 3
}
},
{
"_index": "demo3_indexname",
"_type": "_doc",
"_id": "1",
"_score": 0.603535,
"_source": {
"name": "tom",
"age": 20,
"address": "北京朝阳北花园",
"id": 1
}
},
{
"_index": "demo3_indexname",
"_type": "_doc",
"_id": "2",
"_score": 0.13353139,
"_source": {
"name": "jack",
"age": 20,
"address": "北京昌平北花园",
"id": 2
}
}
]
}
}
|