写点什么

GitHub 星标数超 4 万的火爆之作——ElasticSearch,你值得拥有!

用户头像
飞飞JAva
关注
发布于: 2021 年 05 月 08 日
GitHub星标数超4万的火爆之作——ElasticSearch,你值得拥有!

Hello,今天给各位童鞋们分享 ElasticSearch,赶紧拿出小本子记下来吧!

(一)介绍

ElasticSearch 的目标就是实现搜索。在数据量少的时候,我们可以通过索引去搜索关系型数据库中的数据,但是如果数据量很大,搜索的效率就会很低,这个时候我们就需要一种分布式的搜索引擎。Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful web 接口。

ES 主要用于全文检索、结构化搜索以及分析。ES 的应用十分广泛,比如维基百科、Github 等都使用 ES 实现搜索。

(二)核心概念理解

2.1 数据结构

ES 既然是用来搜索的,那么它必然也需要存储数据。在 Mysql 等关系型数据库中,数据的存储遵循下面的逻辑:

一个数据库(database)中有多个表(tables),每个表有多行数据(rows),每一行数据由多个字段(columns)组成。

ES 中的存储是这样的:

一个索引(indeces)相当于一个数据库(database),每个索引中有多个类型 types(相当于表结构),每个索引中有多个 documents(相当于行),每个 documents 由多个 fields 组成(相当于字段)。

你可以把 ES 理解为他是一个面向文档的数据库。下面用一张图描述 ES 和关系型数据库之间的相似之处:

值得注意的是,在 ES7.x 版本中,types 将慢慢被遗弃,在 8.x 版本中,types 将会彻底弃用。

2.2 索引(indeces)和文档(documents)

ES 中的索引和 Mysql 中的索引不是同一种东西,ES 中的索引是一个文档的集合,索引就是一个数据库。

前面说了 ES 是面向文档的,文档是 ES 中最重要的单位,文档就是一条条的数据。文档中有几个重要的概念:

1、一篇文档中包含多个 key:value

2、文档其实就是一个 JSON 字符串

2.3 分片

ES 是一个分布式搜索引擎,分片就是把一堆数据分布到多个分片中。而索引是对每个分片的一个备份,这些副本同样能处理查询请求。

现在假设集群有两个 node 节点,设置分片数是 5 个,副本数是 1 个,那么数据存储结构将变成下面这样,可以保证副本和分片在不同的节点上:

2.4 倒排索引

为什么 ES 的搜索这么快,和其中所使用的倒排索引也有一定的关系。倒排索引建立的是分词和文档之间的映射关系。下面通过一个简单的例子来讲解一下什么是倒排索引

原来的数据中我们通过文档 ID 去关联标签,但是在查询时就需要遍历所有文档。通过倒排索引,我们可以通过关键词来找到最匹配的文档。

(三)ES 的基本操作

ES 是基于 Restful 风格进行操作的,因此对于习惯了写 crud 的程序员来说,ES 很容易上手。ES 的操作可以使用 Kibana,也可以使用 Postman 直接调用,因为归根结底它就是一个 restful 的操作。我这里使用 Idea 的 ES 插件直接调用。

3.1 创建文档

PUT http://ip:port/索引名/类型名/文档 id

{

"key":"value"

}

因为类型名在后续的版本中将会被删除,这里可以用_doc 代表默认类型:

PUT http://ip:port/索引名/_doc/文档 id

下面给出操作截图

通过 put 创建一个索引之后,我们可以在 head 中看到对应的数据

3.2 创建带有数据类型的索引

3.1 中创建数据时,没有指定具体的数据类型,我们当然也可以为索引指定数据类型

PUT http://ip:port/索引名

参数示例:

{

"mappings": {

"properties": {

"name": {

"type": "text"

},

"address": {

"type": "text"

}

}

}

}

ES 中的核心数据类型如下:

(1)字符串类型: text, keyword

(2)数字类型:long, integer, short, byte, double, float, half_float, scaled_float

(3)日期:date

(4)日期 纳秒:date_nanos

(5)布尔型:boolean

(6)Binary:binary

(7)Range: integer_range, float_range, long_range, double_range, date_range

3.3 查看索引或者文档的数据

通过 GET 请求可以查看索引以及文档的信息:

GET http://ip:port/索引名 #查看索引

GET http://ip:port/索引名/类型名/文档 ID #查看文档

3.4 修改数据

修改数据和创建数据一样,通过 PUT 操作就会更新原来的数据:

PUT http://ip:port/索引名/类型名/文档 id

{

"key":"value"

}

如果是修改的话,响应结果中的 version 就会增加。

另外一种方法是使用 Post 请求:

POST http://ip:port/索引名/类型名/文档 id/_update

参数实例:

{

"doc": {

"name": "javayz4"

}

}

更推荐使用这种方式,如果使用 PUT 方法忘了加某个 key,更新就会变成新增

3.5 删除数据

通过 DELETE 的方式删除数据

DELETE http://ip:port/索引名/类型名/文档 id #删除具体的文档

DELETE http://ip:port/索引名 #删除索引

(四)ES 的搜索操作

ES 最重要的就是它的搜索操作了。

4.1 简单搜索

直接将搜索的参数带到链接中:

GET http://ip:port/索引名/_search?q=key:value

结果如下:

4.2 通过 param 传递参数

除了将参数放到链接当中,还可以将参数通过 JSON 请求体的方式传递,其中 from 和 size 是分页的参数query 中传递查询条件_source 表示结果中要展示的列,不写就表示展示所有。

GET http://ip:port/索引名/_search

参数示例:

{

"from": 0,

"size": 20,

"query": {

"match": {

"name": "javayz2"

}

},

"_source": ["name","address"]

}

除了上面示例中的这些参数之外,还有很多参数可以使用,比如排序

"sort": [

{

"age": {

"order": "desc"

}

}

]

多条件查询:must 表示下面的两个条件都要满足,还可以填 should,表示任意满足其中一个条件即可,或者是 must_not,表示 must 的相反值

"query": {

"bool": {

"must": [

{

"match": {

"name": "javayz"

}

},

{

"match": {

"address": "hz"

}

}

]

}

}

如果你的数据中存在集合,可以通过空格对多个条件进行查询:

查询过程中还支持高亮查询

"highlight":{

"pre_tags": "<em>",

"post_tags": "</em>",

"fields": {

"name": {}

}

}

(五)分词器

所谓分词器,就是将一段话分成一个个关键字,搜索时就按照这些关键字进行搜索。比较好用的分词器有中文的 IK 分词器。

基本使用

给出下载链接:https://github.com/medcl/elasticsearch-analysis-ik/releases

下载和自己 ES 相同的版本,在 plugin 目录下新建一个 ik 文件夹,将下载的文件解压到 ik 目录下,重新启动即可。

IK 分词器提供了两种算法:

1、ik_smart:最少切分

2、ik_max_word:最细粒划分

首先最少切分是根据字典给出最少的切分:

ik_max_word 是最细粒划分,他会给出最多的结果:

{

"analyzer": "ik_max_word",

"text": "我是 Java 工程师"

}

结果:

{

"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": "java",

"start_offset": 2,

"end_offset": 6,

"type": "ENGLISH",

"position": 2

},

{

"token": "工程师",

"start_offset": 6,

"end_offset": 9,

"type": "CN_WORD",

"position": 3

},

{

"token": "工程",

"start_offset": 6,

"end_offset": 8,

"type": "CN_WORD",

"position": 4

},

{

"token": "师",

"start_offset": 8,

"end_offset": 9,

"type": "CN_CHAR",

"position": 5

}

]

}

好啦,今天的文章就到这里,希望能帮助到屏幕前迷茫的你们!​

用户头像

飞飞JAva

关注

还未添加个人签名 2021.04.28 加入

分享、普及java相关知识

评论

发布
暂无评论
GitHub星标数超4万的火爆之作——ElasticSearch,你值得拥有!