本文从基本概念、基本CRUD操作、倒排索引原理、分词等部分来初识Elasticsearch。

2.1 基本概念

Elasticsearch是面向文档(Document)的,文档是所有可搜索数据的最小单位;文档会被序列化成Json格式,保存在Elasticsearch中,并且每个文档都有一个唯一ID,可以通过Elasticsearch自动生成,也可以自己进行指定。对比MySQL,每行数据都有一个主键,这个主键可以使用MySQL自增主键,也可以通过雪花算法等方式生成然后进行自己设置。

文档的元数据,用于标注文档的相关信息。例如:_index表示文档所属的索引名,_id表示文档唯一ID,_score表示相关性打分,_source是文档的原始Json数据等。

索引(Index)是文档的容器,是一类文档的集合。对比MySQL,可以认为索引为一个数据表。

Mapping用来定义字段名和类型,对比MySQL,每个表有表结构的定义,包括字段名称,字段类型等。与关系型数据库进行类比:

RDBMS Elasticsearch
Table Index
Row Document
Column Field
Schema Mapping
SQL DSL

节点是一个Elasticsearch的实例,本质上是一个Java进程。一台机器上可以运行多个Elasticsearch进程,但是生产环境一般建议一台机器上值运行一个Elasticsearch实例。节点分为数据节点和协调节点。数据节点是保存数据的节点,协调节点负责接收Client的请求,将请求路由到到合适的节点,并将结果汇集到一起。

集群是有多个节点组成的。

分片分为主分片和副本,每个分片可以设置一定数量的副本。主分片用于解决数据的水平扩展问题,通过主分片可以将数据分布到集群内的所有节点上。副本是用来解决数据高可用的问题,副本是主分片的拷贝,副本分片数可以动态调整,增加副本数,可以在一定程度上提高服务的可用性。当然副本可以提供查询功能,分摊系统的读负载。例如下图中,分片数为3,副本数为1。



对于分片的设定,生产环境中分片的设定需要提前进行规划。分片数量设置过小会导致后续无法增加节点实现水平扩展;而单个分片数据量太大,会导致数据重新分片耗时。分片数设置过大,会影响搜索结果的相关性打分,影响统计结果的准确性;而单个节点上有过多的分片,会导致资源浪费,同时会影响性能。

2.2 基本CRUD操作与批量操作

Elasticsearch对外提供RESTful API用于CRUD。使用RESTful API与Elasticsearch进行交互有两种方式:curl命令行和Kibana DevTools。可以直接使用Kibana DevTool与Elasticsearch进行交互。

2.2.1 索引操作

  1. 创建索引

    request: PUT /test_index

    response:
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "test_index"
}
  1. 查看现有索引

    request:GET _cat/indices

    response:green open test_index GRXXECvrQjuNKRog7aDkPQ 1 1 2 3 28.9kb 14.4kb

  2. 删除索引

    request:DELETE /test_index

    response:

{
"acknowledged" : true
}

2.2.2 文档操作

  1. 指定id创建文档

request:

PUT /test_index/_doc/1
{
"username":"Paul",
"age":10
}

response:

{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
  1. 不指定id创建文档

request:

POST /test_index/_doc
{
"username":"Rose",
"age":11
}

response:

{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "soOv1HcB4Isa6tvVdQ9J",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
  1. 指定id查询文档

request:GET /test_index/_doc/1

response:

{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"username" : "Paul",
"age" : 10
}
}
  1. 查询所有文档

request:GET /test_index/_search

response:

{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"username" : "Paul",
"age" : 10
}
},
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "soOv1HcB4Isa6tvVdQ9J",
"_score" : 1.0,
"_source" : {
"username" : "Rose",
"age" : 11
}
}
]
}
}
  1. 更新文档

request:

POST /test_index/_update/1
{
"doc": {
"username": "Paul",
"age": 20
}
}

response:

{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 1
}
  1. 删除文档

request:DELETE /test_index/_doc1

2.2.3 批量操作

批量操作可以减少网络连接所产生的开销,提高性能。

  • _bulk

支持在一次API调用中,对不同的索引进行操作。

bulk支持Index、Create、Update?Delete四种操作。

请求中单条操作失败,并不会影响其他操作,返回结果中包含每一条操作的执行结果。

request:

POST _bulk
{"index":{"_index":"test_index", "_id":"1"}}
{"username":"Smart", "age":22}
{"delete":{"_index":"test_index", "_id":"2"}}

response:

{
"took" : 95,
"errors" : false,
"items" : [
{
"index" : {
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_version" : 5,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 1,
"status" : 200
}
},
{
"delete" : {
"_index" : "test_index",
"_type" : "_doc",
"_id" : "2",
"_version" : 1,
"result" : "not_found",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 6,
"_primary_term" : 1,
"status" : 404
}
}
]
}
  • 批量读取mget

request:

GET _mget
{
"docs":[
{
"_index":"test_index",
"_id":1
},
{
"_index":"movies",
"_id":1
}]
}

response:

{
"docs" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"_seq_no" : 2,
"_primary_term" : 1,
"found" : true,
"_source" : {
"username" : "Paul",
"age" : 20
}
},
{
"_index" : "movies",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 6,
"_primary_term" : 1,
"found" : true,
"_source" : {
"id" : "1",
"title" : "Toy Story",
"year" : 1995,
"genre" : [
"Adventure",
"Animation",
"Children",
"Comedy",
"Fantasy"
],
"@version" : "1"
}
}
]
}
  • 批量查询msearch

request:

POST test_index/_msearch
{}
{"query":{"match_all":{}},"size":1}
{"index":"kibana_sample_data_flights"}
{"query":{"match_all":{}},"size":2}

response:

{
"took" : 4,
"responses" : [
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "test_index",
"_type" : "_doc",
"_id" : "soOv1HcB4Isa6tvVdQ9J",
"_score" : 1.0,
"_source" : {
"username" : "Rose",
"age" : 11
}
}
]
},
"status" : 200
},
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 10000,
"relation" : "gte"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "kibana_sample_data_flights",
"_type" : "_doc",
"_id" : "iTmvUXcBNxIYppLoFWwg",
"_score" : 1.0,
"_source" : {
"FlightNum" : "R3J7URU",
"DestCountry" : "US",
"OriginWeather" : "Hail",
"OriginCityName" : "Moscow",
"AvgTicketPrice" : 1172.5681640799792,
"DistanceMiles" : 5149.888524287689,
"FlightDelay" : false,
"DestWeather" : "Rain",
"Dest" : "Spokane International Airport",
"FlightDelayType" : "No Delay",
"OriginCountry" : "RU",
"dayOfWeek" : 6,
"DistanceKilometers" : 8287.942197231247,
"timestamp" : "2021-02-14T10:59:03",
"DestLocation" : {
"lat" : "47.61989975",
"lon" : "-117.5339966"
},
"DestAirportID" : "GEG",
"Carrier" : "ES-Air",
"Cancelled" : false,
"FlightTimeMin" : 753.4492906573861,
"Origin" : "Sheremetyevo International Airport",
"OriginLocation" : {
"lat" : "55.972599",
"lon" : "37.4146"
},
"DestRegion" : "US-WA",
"OriginAirportID" : "SVO",
"OriginRegion" : "RU-MOS",
"DestCityName" : "Spokane",
"FlightTimeHour" : 12.557488177623101,
"FlightDelayMin" : 0
}
},
{
"_index" : "kibana_sample_data_flights",
"_type" : "_doc",
"_id" : "ijmvUXcBNxIYppLoFWwg",
"_score" : 1.0,
"_source" : {
"FlightNum" : "OE9TTXI",
"DestCountry" : "GB",
"OriginWeather" : "Sunny",
"OriginCityName" : "Guangzhou",
"AvgTicketPrice" : 834.6361636829536,
"DistanceMiles" : 5911.063226254684,
"FlightDelay" : false,
"DestWeather" : "Thunder & Lightning",
"Dest" : "London Heathrow Airport",
"FlightDelayType" : "No Delay",
"OriginCountry" : "CN",
"dayOfWeek" : 6,
"DistanceKilometers" : 9512.93413679362,
"timestamp" : "2021-02-14T08:13:00",
"DestLocation" : {
"lat" : "51.4706",
"lon" : "-0.461941"
},
"DestAirportID" : "LHR",
"Carrier" : "JetBeats",
"Cancelled" : true,
"FlightTimeMin" : 500.68074404176946,
"Origin" : "Guangzhou Baiyun International Airport",
"OriginLocation" : {
"lat" : "23.39240074",
"lon" : "113.2990036"
},
"DestRegion" : "GB-ENG",
"OriginAirportID" : "CAN",
"OriginRegion" : "SE-BD",
"DestCityName" : "London",
"FlightTimeHour" : 8.344679067362824,
"FlightDelayMin" : 0
}
}
]
},
"status" : 200
}
]
}

2.3 倒排索引

2.3.1 正排索引与倒排索引

什么是正排索引?正排索引指的是从文档Id到文档内容、单词的关联关系。例如每本书的目录,通过目录可以很快找到某个标题的具体内容在书中的那一页。

什么是倒排索引?倒排索引指的文档内容或者单词到文档Id的关联关系。还是以书的例子,倒排索引指的是从具体内容到文章标题的索引。

知乎上面有人举了一个形象的例子。比如说考我们一首诗,给一首诗的名字,通常大家都可以背下来诗的内容。那为什么“飞花令”的时候我们想不起来诗句呢?因为我们的大脑中没有建立从诗句中某个字到诗名的倒排索引,假如说建立了这样的倒排索引,我们也可以像中国诗词大会的选手一样飞来飞去。

文档ID 文档内容
1 Elasticsearch是最流行的搜索引擎
2 Java是世界上最好的语言
3 Google是全球最大的搜索引擎
单词 文档ID列表
elasticsearch 1
流行 1
搜索引擎 1,3
java 2
世界 2
最好 2
语言 2
google 3
全球 3
最大 3

Elasticsearch存储的是一个json格式的文档,其中包含多个字段,每个字段都会有自己的倒排索引。

那倒排索引是如何产生的呢?是文档内容分词之后和文档ID进行关联。

2.4 分词

分词是指将连续的字符串按照一定的规则重新切分成为单词(term or token)的过程,在ES里面叫做Analysis。

2.4.1 ES分词器组成和自带分词器

Analyzer是ES中专门处理分词的组件,组成如下:

  • Character Filters:针对原始文本进行处理,比如去除HTML特殊标识符等
  • Tokenizer:将原始文本按照一定规则切分成为单词
  • Token Filters:针对Tokenizer处理的单词进行再加工,比如转小写、删除停用词或者新增同义词等处理

其工作过程如图所示:

Elasticsearch内置分词器

分词器 说明
Standard Analyzer 默认分词器,按词切分,小写处理,停用词处理默认关闭
Simple Analyzer 按照非字母切分,非字母的都被去除,小写处理
Stop Analyzer 小写处理,停用词过滤
Whitespace Analyzer 按照空格切分,不转小写
Keyword Analyzer 不分词,直接将输入内容进行输出
Pattern Analyzer 正则表达式,默认\W+(非字母符号分割)
Language 提供30多种常见语言的分词器
Customer Analyzer 自定义分词器

测试一下:

  • 直接指定Analyzer进行测试
GET /_analyze
{
"analyzer": "standard",
"text": [
"Hello World, Hello Elasticsearch"
]
}
  • 指定索引的字段进行测试
POST /movies/_analyze
{
"field": "title",
"text": [
"Hello World, Hello Elasticsearch"
]
}
  • 自定义分词器进行测试
POST /_analyze
{
"tokenizer": "standard",
"filter": [
"lowercase"
],
"text": [
"Hello World, Hello Elasticsearch"
]
}

2.4.2 Analyze API使用

ES提供一个测试分词的API接口,方便验证分词效果。_analyze

可以直接指定analyzer进行测试

可以直接指定索引中的字段进行测试:GET test_index/_analyze

可以自定义分词器进行测试

至此,学习了基本API的使用、批量操作、倒排索引原理和分词等概念,对ELasticsearch有了初步的认识。

Elasticsearch核心技术(二):Elasticsearch入门的更多相关文章

  1. Elasticsearch入门教程(六):Elasticsearch查询(二)

    原文:Elasticsearch入门教程(六):Elasticsearch查询(二) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:h ...

  2. Elasticsearch 之聚合分析入门

    本文主要介绍 Elasticsearch 的聚合功能,介绍什么是 Bucket 和 Metric 聚合,以及如何实现嵌套的聚合. 首先来看下聚合(Aggregation): 什么是 Aggregati ...

  3. Elasticsearch核心技术(1)--- Docker容器中运行ES、Kibana、Cerebro

    Docker容器中运行ES,Kibana,Cerebro和Logstash安装与数据导入ES 想加强ES有关的知识,看了阮一鸣老师讲的<Elasticsearch核心技术与实战>收获很大, ...

  4. Elasticsearch核心技术(2)--- 基本概念(Index、Type、Document、集群、节点、分片及副本、倒排索引)

    Elasticsearch核心技术(2)--- 基本概念 这篇博客讲到基本概念包括: Index.Type.Document.集群,节点,分片及副本,倒排索引. 一.Index.Type.Docume ...

  5. ElasticSearch(二):文档的基本CRUD与批量操作

    ElasticSearch(二):文档的基本CRUD与批量操作 学习课程链接<Elasticsearch核心技术与实战> Create 文档 支持自动生成文档_id和指定文档_id两种方式 ...

  6. ElasticSearch 连载二 中文分词

    ElasticSearch 连载二 中文分词 上一章ElasticSearch 连载一 基础入门 对Elastic的概念.安装以及基础操作进行了介绍. 那是不是有童鞋会有以下几个问题呢? 什么是中文分 ...

  7. springboot整合es客户端操作elasticsearch(二)

    在上章节中整合elasticsearch客户端出现版本问题进行了处理,这章来进行springboot整合得操作 环境:elaticsearch6.2.1,springboot 2.1.8 客户端版本采 ...

  8. Elasticsearch笔记二之Curl工具基本操作

    Elasticsearch笔记二之Curl工具基本操作 简介: Curl工具是一种可以在命令行访问url的工具,支持get和post请求方式.-X指定http请求的方法,-d指定要传输的数据. 创建索 ...

  9. elasticsearch(二) 之 elasticsearch安装

    目录 elasticsearch 安装与配置 安装java 安装elastcsearch 二进制安装(tar包) 在进入生产之前我们必须要考虑到以下设置 增大打开文件句柄数量 禁用虚拟内存 合适配置的 ...

  10. Elasticsearch教程(二)java集成Elasticsearch

    1.添加maven <!--tika抽取文件内容 --> <dependency> <groupId>org.apache.tika</groupId> ...

随机推荐

  1. 资源:HTML调色板

    调色板路径 https://encycolorpedia.cn/

  2. (转) PHP实现从1累加到100(1+2+….+100=)的几种思路,挺有意思的!!!

    一个经典的小学问题也是一个简单的PHP小应用,1+2+3--100=多少?使用PHP应该怎么写? 这里总结了以下几种思路: 1.普通PHPer: $sum=0;for($i=1;$i<=100; ...

  3. XCTF Normal_RSA

    这题本来算是很常规的rsa了,下载附件 发现有个公钥文件,还有一个加密文件,这种题之前有遇到一次,做法和这个类似,上次那个是用rsa的库,直接解的,这次直接用常规的,好像更简单,记录下模板 记事本打开 ...

  4. CG-CTF WxyVM

    一. 之前一直以为虚拟机是那种vmp的强壳,下午看了一些文章才逐渐明白虚拟机这个概念,目前ctf中题目出现的都是在程序中相等于内嵌了一个虚拟机,将程序代码转换成自己定义的指令,通过内嵌的虚拟机进行解释 ...

  5. ESP32-mqtt笔记

    基于ESP-IDF4.1 #include <stdio.h> #include <stdint.h> #include <stddef.h> #include & ...

  6. Linux | Shell流程控制语句

    流程控制语句 简单的Shell 脚本还不能满足我们日常工作的需要要,因为他不能批量的帮我们完成工作,所以Shell引入了 if.for.while.case 4种流程控制语句来帮助我们完成工作. if ...

  7. 虚拟局域网VLAN简介

    VLAN 1.根据端口划分VLAN 2.根据MAC地址划分VLAN 3.根据网络层划分VLAN 4. IP组播作为VLAN VLAN优点 1.减少移动和改变的代价 2.虚拟工作组 3.限制广播包 4. ...

  8. 达梦数据库(DM8)大规模并行集群MPP 2节点安装部署

    达梦数据库大规模并行集群MPP 2节点安装部署   1.环境准备   os 数据库版本 ip mpp角色 centos7.x86 DM8 192.168.30.100 mpp1 centos7.x86 ...

  9. sqliab刷题笔记-联合注入

    Less-1 测试是字符型还是数字型 判断所在字段数 查看显示值 可以看出显示2,3位置.因此我们选择2的位置进行联合注入 查看表名 我们要对admin,users等字符敏感 查看admin表中的字段 ...

  10. Leetcode:面试题28. 对称的二叉树

    Leetcode:面试题28. 对称的二叉树 Leetcode:面试题28. 对称的二叉树 Talk is cheap . Show me the code . /** * Definition fo ...