首页 > 其他 > 详细

ElasticSearch 副本-02【ES 核心概念及 IK 分词器】

时间:2020-04-22 22:47:18      阅读:81      评论:0      收藏:0      [点我收藏+]

ElasticSearch 核心概念理解

ElasticSearch 是面向文档的。

RDBMS 和 ElasticSearch 客观对比:

RDBMS ElasticSearch
数据库(Database) 索引(Index)
表(Table) Type(即将弃用)
行(Row) Document
字段(Column) Field

ElasticSearch 中可以包含多个索引,每个索引中可以包含多个类型,每个类型下面又包含多个文档,每个文档中又包含多个字段。

物理设计

ElasticSearch(集群) 在后台把每个索引划分成多个分片,每个分片可以在集群中的不同服务器之间迁移。

逻辑设计

一个索引类型中,包含多个文档。比如说文档1、文档2、.... 。当我们索引一篇文档时,可以通过这样的顺序找到它:索引?类型?文档ID(这里的ID不是整数,而是一个字符串),通过这个组合我们就能索引到某个具体的文档。

索引

索引是映射类型的容器,ElasticSearch 中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置,然后它们被存储到了各个分片上。

物理设计:节点和分片如何工作

一个集群至少有一个主节点,而一个节点就是一个 ElasticSearch 进程。节点可以有多个索引,如果你创建索引,那么索引将会有 5 个分片(Primary Shard,又称主分片)构成的,每一个分片会有一个副本(Replica Shard,又称复制分片)。

技术分享图片

上图是一个有 3 个节点的 ElasticSearch 集群,可以看见主分片和对应的复制分片都不会在同一个节点内,这样有利于某个节点挂掉了,数据也不至于丢失。实际上,一个分片是一个 Lucene 索引,一个包含倒排索引的文件目录,倒排索引的结构使得 ElasticSearch 在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字。

倒排索引(重要)

ElasticSearch 使用的是一种称之为 倒排索引 的结构,采用 Lucene 倒排索引作为底层。这种结构适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有包含它的文档列表。

例如:现在有两个文档,每个文档包含如下内容:

be careful, come back, get to		# 文档1的内容

come from, be free, have a talk		# 文档2的内容

为了创建倒排索引, 首先要将每个文档拆分成独立的词(或称为词条或 tokens),然后创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档:

term doc_1 doc_2
be
careful ×
com
back ×
get ×
to ×
from ×
free ×
have ×
a ×
talk ×

现在我们需要搜索 be free,只需要查看包含每个词条的文档

term doc_1 doc_2
be
free ×
total 1 2

两个文档都匹配,但是第二个文档比第一个文档匹配程度更高。如果没有其它条件,这两个包含关键字的文档都将返回。

再比如博客可以通过标签来搜索博客文章,那么倒排索引列表就是这样一个结构:

博客文章(原始数据)
博客文章ID 标签
1 Java
2 Python
3 TypeScript
4 Go
5 Java, Python
6 JavaScript, TypeScript

索引列表(倒排索引)
标签 博客文章ID
Java 1, 5
Python 2, 5
Go 4
JavaScrpt 6
TypeScript 6

如果要搜索含有 Java 标签的文章,那相对与查找所有原始数据而言,查找倒排索引后的数据将会快得多,只需要查看标片这一栏,然后获取相关的文章ID即可,过滤掉无关的文章,提高效率

ElasticSearch 的索引和 Lucene 的索引对比:

在 ElasticSearch 中,索引这个词被频繁使用,这就是术语的使用。在 ElasticSearch 中,索引被分为多个分片,每个分片是一个 Lucene 的索引,所以一个 ElasticSearch 索引是由多个 Lucene 索引组成的

类型

类型是文档的逻辑容器,就像关系型数据库一样,表格是行的容器。类型中对于字段的定义成为映射,比如 name 映射为字符串类型。文档无模式的,它们不需要拥有映射中所定义的所有字段,比如新增一个字段。那么 ElasticSearch 是怎么做到的呢?ElasticSearch 会自动的将新字段加入映射,但是这个字段不确定它是什么类型,ElasticSearch 就开始猜测,如果这个值是18,那么 ElasticSearch 会任何它是整形。但是 ElasticSearch 也可能猜不对,所以最安全的方式就是提前定义好所需要的映射。

文档

文档是可以被索引的基本数据单位。存储在 ElasticSearch 中的主要实体叫文档 document,可以理解为关系型数据库中表的一行记录。在 ElasticSearch 中,文档有几个重要的属性:

  • 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含 Key 和 Value
  • 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的
  • 灵活的结构,文档不依赖预先定义的模式。在关系型数据库中,字段必须提前定义才能使用。而在 ElasticSearch 中对于字段是非常灵活的。有时候我们可以忽略该字段或者动态添加一个新字段。

尽管我们可以随意的新增或忽略某个字段,但是每个字段的类型非常重要。比如一个年龄字段类型可以是整数也可以是字符串,因为 ElasticSearch 会保存字段和类型之间的映射和其他的设置。

IK 分词器插件

分词:即把一段中文或其他语言拆分成一个个的关键字,我们在搜索的时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词器是将每个字看作一个词。比如 "引导未来" 会被拆分成 ”引“,”导“,”未“,”来“,这显然是不符合要求的,所以我们需要安装中文分词器 IK 来解决这个问题。

? 如果使用中文,推荐使用 IK 分词器!

IK 提供了两种分词算法:

  • ik_smart(最少切分)
  • ik_max_word(最细粒度划分)

安装 Ik 分词器

docker-compose.yml 同级目录下新建一个文件夹 plugins

touyel@server:/usr/local/docker/elasticsearch$ ls
docker-compose.yml
touyel@server:/usr/local/docker/elasticsearch$ pwd
/usr/local/docker/elasticsearch
touyel@server:/usr/local/docker/elasticsearch$ sudo mkdir plugins
touyel@server:/usr/local/docker/elasticsearch$ ls
docker-compose.yml  plugins

修改 docker-compose.yml 文件:

version: ‘3.1‘

services:
  elasticsearch:
    image: elasticsearch:7.6.2
    container_name: elasticsearch
    restart: always
    environment:
      discovery.type: single-node
    # 增加数据卷
    volumes:
      - ./plugins:/usr/share/elasticsearch/plugins
    ports:
      - 9200:9200
      - 9300:9300
  kibana:
    image: kibana:7.6.2
    container_name: kibana
    environment:
      ELASTICSEARCH_URL: "127.0.0.1:9200"
      I18N_LOCALE: "zh-CN"
    ports:
      - 5601:5601

到 GitHub 上下载 elasticsearch-analysis-ik,注意与 ElasticSearch 版本对应

解压后上传到 plugins 目录下

为了防止权限不足导致上传失败,先获取 plugins 目录的所有权限:

sudo chmod 777 plugins/

然后再进行上传

技术分享图片

重启 ElasticSearch,观察:

docker-compose down


docker-compose up -d


docker-compose logs | grep "loaded plugin"

# 可以看见,加载了 IK 分词器插件
elasticsearch    | {"type": "server", "timestamp": "2020-04-22T12:35:19,584Z", "level": "INFO", "component": "o.e.p.PluginsService", "cluster.name": "docker-cluster", "node.name": "78e45fed0030", "message": "loaded plugin [analysis-ik]" }

进入 ElasticSearch 容器使用 elasticsearch-plugins 命令查看下:

技术分享图片

使用 kibana 进行测试

最少切分

技术分享图片


最细粒度划分

技术分享图片


搜索:我是混子叶

技术分享图片

发现问题:我想 ”混子叶“ 成为一个词,怎么办?

这种自己需要的词,需要自己加到分词器的字典中!

IK 分词器增加自己的配置

1、进入 IK 分词器的配置目录

touyel@server:/usr/local/docker/elasticsearch$ ls
docker-compose.yml  plugins
touyel@server:/usr/local/docker/elasticsearch$ cd plugins/analysis-ik/config/
touyel@server:/usr/local/docker/elasticsearch/plugins/analysis-ik/config$ ls
extra_main.dic         extra_single_word_full.dic      extra_stopword.dic  main.dic         quantifier.dic  suffix.dic
extra_single_word.dic  extra_single_word_low_freq.dic  IKAnalyzer.cfg.xml  preposition.dic  stopword.dic    surname.dic
touyel@server:/usr/local/docker/elasticsearch/plugins/analysis-ik/config$ ll
total 8268
drwxrwxr-x 2 touyel touyel    4096 Apr 22 20:32 ./
drwxrwxr-x 3 touyel touyel    4096 Apr 22 20:32 ../
-rw-rw-r-- 1 touyel touyel 5225922 Apr 22 20:32 extra_main.dic
-rw-rw-r-- 1 touyel touyel   63188 Apr 22 20:32 extra_single_word.dic
-rw-rw-r-- 1 touyel touyel   63188 Apr 22 20:32 extra_single_word_full.dic
-rw-rw-r-- 1 touyel touyel   10855 Apr 22 20:32 extra_single_word_low_freq.dic
-rw-rw-r-- 1 touyel touyel     156 Apr 22 20:32 extra_stopword.dic
-rw-rw-r-- 1 touyel touyel     625 Apr 22 20:32 IKAnalyzer.cfg.xml
-rw-rw-r-- 1 touyel touyel 3058510 Apr 22 20:32 main.dic
-rw-rw-r-- 1 touyel touyel     123 Apr 22 20:32 preposition.dic
-rw-rw-r-- 1 touyel touyel    1824 Apr 22 20:32 quantifier.dic
-rw-rw-r-- 1 touyel touyel     164 Apr 22 20:32 stopword.dic
-rw-rw-r-- 1 touyel touyel     192 Apr 22 20:32 suffix.dic
-rw-rw-r-- 1 touyel touyel     752 Apr 22 20:32 surname.dic

2、新建一个 touyel.dic 文件,文件名自己随便写一个就行,最好有意义。

sudo vim touyel.dic

输入自己的词,比如我想 ”混子叶“ 成为一个词。

# touyel.dic
混子叶

3、编辑 IKAnalyzer.cfg.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 扩展配置</comment>
        <!--用户可以在这里配置自己的扩展字典 -->
    	<!--添加我们自己的字典 -->
        <entry key="ext_dict">touyel.dic</entry>
         <!--用户可以在这里配置自己的扩展停止词字典-->
        <entry key="ext_stopwords"></entry>
        <!--用户可以在这里配置远程扩展字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--用户可以在这里配置远程扩展停止词字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

4、重启 ElasticSearch

docker-compose down
docker-compose up -d

查看日志,发现加载了我们自己的字典!

技术分享图片

启动成功后,进入 kinaba 测试:

技术分享图片

Nice!??

ElasticSearch 副本-02【ES 核心概念及 IK 分词器】

原文:https://www.cnblogs.com/touyel/p/12756385.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!