本文从基本概念、基本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. Linux:linux服务器稳定性压力测试工具stress安装与使用

    stress是一个linux下的压力测试工具,专门为那些想要测试自己的系统,完全高负荷和监督这些设备运行的用户. 1. stress1.0.4下载地址 下载:https://fossies.org/l ...

  2. 从 Java 代码到 Java 堆

    本文将为您提供 Java 代码内存使用情况的深入见解,包括将 int 值置入一个 Integer 对象的内存开销.对象委托的成本和不同集合类型的内存效率.您将了解到如何确定应用程序中的哪些位置效率低下 ...

  3. kafka 安装和配置

    转载自:https://www.cnblogs.com/heijinli/p/13545182.html 下载及安装  第一步:进入kafka官网  按照自己的需求选择版本,我这里选择 最新版的 2. ...

  4. PHP解决并发问题的几种实现(转)

      对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了 在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制. 方案一:使用文件锁排它锁 ...

  5. 容器化-Docker-1-速查手册-Docker常用命令

    目录 备注 常用命令 Docker镜像管理(操作对象是镜像) Docker容器管理(操作对象是容器) 容器外挂目录(宿主目录映射到容器中) 这篇文章的目的就是把最常用的命令列出来,没时间看速查命令使用 ...

  6. Kubernetes全栈架构师(二进制高可用安装k8s集群部署篇)--学习笔记

    目录 二进制高可用基本配置 二进制系统和内核升级 二进制基本组件安装 二进制生成证书详解 二进制高可用及etcd配置 二进制K8s组件配置 二进制使用Bootstrapping自动颁发证书 二进制No ...

  7. C语言:整数取值范转及溢出

    short.int.long 是C语言中常用的三种整数类型,分别称为短整型.整型.长整型.在现代操作系统中,short.int.long 的长度分别是 2.4.4 或者 8,它们只能存储有限的数值,当 ...

  8. sql2008编辑前200行怎么修改

    打开Microsoft SQL Server Management Studio--工具菜单--选项---SQL Server对象资源管理器---命令--右侧"编辑前n行命令的值:1000

  9. Java基础00-第一个程序2

    1. 常用DOS命令 1.1 打开命令提示窗口 按下win+R 输入cmd 按下回车键 得到命令提示窗口 1.2 常用命令 2. Path环境变量的配置 2.1 为什么要配置Path环境变量 2.2 ...

  10. C语言怎么实现可变参数

    可变参数 可变参数是指函数的参数的数据类型和数量都是不固定的. printf函数的参数就是可变的.这个函数的原型是:int printf(const char *format, ...). 用一段代码 ...