技术先知第5期:ElasticSearch全文检索技术分享

技术需要被交流才能加快进步,知识需要分享才能传播的更远。

无论是向他人请教也好,还是从网上查找到的知识也好,技术的增长都是得自于他人给你做的无私分享。

——进步始于交流,收获源于分享!

抛砖引玉后,重磅来袭。

2018年11月30日,【嘉诚学院】技术先知第5期分享会再度来袭!Mr.阿土,给研发的伙伴们带来了关于ElasticSearch(简写为“ES”)的精彩技术分享。凭借多方面的了解,Mr.阿土结合其工作经验及相关案例,由浅入深地逐步讲解:ES简介、ES数据存储、ES数据分析以及如何实现精确查询。

ElasticSearch简介

Part 1

1

ES是什么

ElasticSearch(ES)是一个基于Lucene构建的开源、分布式、RESTful的全文搜索引擎。

ES能够横向扩展至数以百计的服务器存储以及处理PB级的数据。可以在极短的时间内存储、搜索和分析大量的数据。即使是亿级以上的数据量,因为底层采用的是倒排索引机制,只要你的服务器资源足够好,理论上随着数据量的增加、索引的增量,实时查询效率是线性的。

Lucene系搜索引擎

LIUS、Solr、Elasticsearch、Katta、Compass等都是基于Lucene封装。

Lucene是目前最为流行的开放源代码全文搜索引擎工具包,它不是一个具有完整特征的搜索应用程序,而是一个专注于文本索引和搜索的工具包,能够为应用程序添加索引与搜索能力。

Lucene的索引数据结构已经成了一种事实上的标准,为许多搜索引擎所采用。

2

ES的几个核心概念

cluster

集群

一个或多个节点(服务器)的集合。一个集群由一个唯一集群ID确定,并指定一个集群名,集群名非常重要,因为节点可以通过这个集群名加入群集。

node

节点

一个es集群由一个或多个节点组成,并且参与数据的索引和提供查询能力。节点的名称在eaalsticsearch.yml中的node.name进行配置,若不进行配置则会使用一个随机的UUID进行标识。

index

索引

索引是一组具有类似特征的文档集合,索引的名称要求必须小写。

type

类型

在索引中,可以定义一个或多个类型。类型是索引的逻辑类别/分区。

document

文档

文档是可以被索引的基本信息单元,类比为数据库的每一条数据。

shard

分片

ES处理的最小单元就是分片,分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。当你的集群规模扩大或者缩小时,ES会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。

replicas

分片副本

就是分片的复制品,它为节点故障提供了高可用性,它还扩展了搜索量和吞吐量,因为搜索可以在所有副本上并行执行。

ES数据存储

Part 2

1

ES存储逻辑和物理设计

逻辑设计:

索引和搜索的基本单位是文档,可以认为它是关系数据库里的一行。文档以类型来分组,类型就包含了若干文档,类似表格包含若干行。最终,一个类型存在于同一索引中,索引是更大的容器,类似SQL世界里的数据库。

物理设计:

在后台,ES将每个索引划分为分片,每份分片可以在集群中的不同节点(服务器)间迁移。物理设计的配置方式决定了集群的性能、可扩展性和可用性。

2

倒排索引

ES引擎把文档数据写入到倒排索引(Inverted Index)的数据结构中,倒排索引建立的是分词(Term)和文档(Document)之间的映射关系,在倒排索引中,数据是面向词(Term)而不是面向文档的。

(简化版的倒排索引如图)

字段值被分析之后,存储在倒排索引中,倒排索引存储的是分词(Term)和文档(Doc)之间的关系,从图中可以看出,倒排索引有一个词条的列表,每个分词在列表中是唯一的,记录着词条出现的次数,以及包含词条的文档。实际上,ElasticSearch引擎创建的倒排索引比这个复杂得多。

3

列式存储

从图的内存结构可以看出,行式存储下,一张表的数据时放在一起的,但是列式存储则是分开保存;查询时只有涉及到的列会被读取;非常适合执行排序和聚合操作。

缺点:选择完成时,被选择的列要重新组装;插入/更新操作比较麻烦。

4

数据安全策略

ES数据分析

Part 3

分析(analysis)是在文档被发送并加入倒排索引之前,ES 会对每个被分析字段进行一系列的处理。

(1)字符过滤:

使用字符过滤器转变字符。

(2)文本切分为分词:

将文本切分为单个或多个分词。

(3)分词过滤:

使用分词过滤器转变每个分词。

(4)分词索引:

分词经过以上一系列处理后,再将这些分词存储到索引中。

最终组成了之前介绍的倒排索引。

1

分析器

2

分词器

中文IK分词器

在使用IK分词器时,为了使查询结果更为精准,我们可以自定义分词,比如法律法规方面的专业词汇,办案流程中的专业术语等等。

IK分词器里的两个策略:ik_max_word 和 ik_smart

ik_max_word:会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合;

ik_smart:会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。

3

分词过滤器

我们在使用过程中可以根据需求自定义分析器,自定义分词,自定义分词过滤器等等,但是要注意的是:

(1)无论自定义什么,必须经过反复测试推敲,因为分析器是存储和查询的基础,这个如果有问题,那么查询结果就可能失之毫厘差之千里。

(2)分析器,分词器如果有变动,ES数据必须重新生成,否则存储方式和搜索会存在误差。

如何精确查询

Part 4

1

查询和过滤器

过滤器和查询的最大区别就是过滤器不计算查询相关度,它不会计算匹配文档的得分,所以过滤器在性能上比查询要快,原因就是它做的工作比较少。因此实际使用中查询配合过滤器使用能提高搜索性能。

查询方法列举:

Match_all

Match

Query_string

Simple_query_string

Term

Terms

Phrase

Prefix

Phrase_prefix

Muti_match

Bool

Range

Wildcard

nested

2

最小匹配度查询

QueryBuilders.multiMatchQuery(Object text, String... fieldNames).minimumShouldMatch(“90%”);

Text 是查询文本, fieldNames是字段数组,意思是对文档中多字段查询,百分数就是最小匹配度。

比如文本查询后有三个分词,这就意味着召回的doc中至少有3*0.9=2.7向下取整2个词条才可以。

3

短语查询

QueryBuilders.matchPhraseQuery(String field, Object value).slop(2) ;

表示将value分词后中间允许存在两个分词结果的词条。

对ES查询控制精确度的几种方法:

(1)用好ES开源代码提供的查询方法,以及一些参数的设置。不得已时可以对开源代码进行重构,以达到实际需求。

(2)在现有中文分词器IK的基础之上进行自定义分词。增加一些专业术语和常用词汇。

(3)根据实际应用自定义字符过滤器,分词过滤器,排除一些没有意义的分词。

等等……

不知不觉,此次分享会已接近尾声,非常感谢Mr.阿土给伙伴们带来专业化的ElasticSearch技术分享!

“他山之石可以攻玉”、“三人行则必有我师”,这些能够流传千年的话总是有一定道理的。

有时间偶尔想想自己所掌握的东西从何而来,然后在力所能及而又合适的时候,把这种观念传递下去……

——这,既是分享,更是感恩!

嘉诚学院期待你的加入!

END

编辑丨李月

审核丨徐兵子

版权信息:嘉诚学院。

从这里了解

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181203G1CCD400?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券