Elasticsearch教程---Lucene简介(一)

第一章 概述

Elasticsearch是一个实时的分布式搜索和分析引擎。它可以帮助你用前所未有的速度去处理大规模数据, 它不但稳定、可靠、快速,而且也具有良好的水平扩展能力,是专门为分布式环境设计的,它可以用于全文搜索,结构化搜索以及分析,当然你也可以将这三者进行组合。Elasticsearch是一个建立在全文搜索引擎 Apache Lucene 基础上的搜索引擎,可以说Lucene是当今最先进,最高效的全功能开源搜索引擎框架。Elasticsearch分布式搜索引擎的总体框架图:
在这里插入图片描述

ElasticSearch是基于Lucene开发的分布式搜索框架,包含如下特性:

  1. 分布式索引、搜索。

  2. 索引自动分片、负载均衡。

  3. 自动发现机器、组建集群。

  4. 支持Restful 风格接口。

  5. 配置简单等。

第二章 Lucene简介

2.1 Lucene简介

Lucene是Apache Jakarta家族中的一个开源项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎、索引引擎和部分文本分析引擎。

Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具,是目前最为流行的基于 Java 开源全文检索工具包。

的数据总体分为两种:

  • 结构化数据:指具有固定格式或有限长度的数据,如数据库、元数据等。
  • 非结构化数据:指不定长或无固定格式的数据,如邮件、word文档等磁盘上的文件。

对于结构化数据的全文搜索很简单,因为数据都是有固定格式的,例如搜索数据库中数据使用SQL语句即可。

对于非结构化数据,有以下两种方法:

  1. 顺序扫描法(Serial Scanning)
  2. 全文检索(Full-text Search)

顺序扫描法
如果要找包含某一特定内容的文件,对于每一个文档,从头到尾扫描内容,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件,因此速度很慢。

全文检索
将非结构化数据中的一部分信息提取出来,重新组织,使其变得具有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。

例如字典的拼音表和部首检字表就相当于字典的索引,通过查找拼音表或者部首检字表就可以快速的查找到我们要查的字。

这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search)。

2.1、全文检索流程

在这里插入图片描述

2.1.1 索引过程

  1. 索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括:确定原始内容即要搜索的内容→采集文档→创建文档→分析文档→索引文档。
  2. 搜索过程,从索引库中搜索内容,搜索过程包括:用户通过搜索界面→创建查询→执行搜索,从索引库搜索→渲染搜索结果。

从上面了解到的知识点也可看出,索引和搜索流程图也可表示为
在这里插入图片描述

总结:全文检索过程分为索引、搜索两个过程:

索引
从关系数据库中、互联网上、文件系统采集源数据(要搜索的目标信息),源数据的来源是很广泛的。
将源数据采集到一个统一的地方,要创建索引,将索引创建到一个索引库(文件系统)中,从源数据库中提取关键信息,从关键信息中抽取一个一个词,词和源数据是有关联的。也即创建索引时,词和源数据有关联,索引库中记录了这个关联,如果找到了词就说明找到了源数据(http的网页、pdf电子书等……)。
搜索

   1. 用户执行搜索(全文检索)编写查询关键字。
   2. 从索引库中搜索索引,根据查询关键字搜索索引库中的一个一个词。
   3. 展示搜索的结果。

2.1.2 创建索引

对文档索引的过程,将用户要搜索的文档内容进行索引,索引存储在索引库(index)中。
这里我们要搜索的文档是磁盘上的文本文件,根据案例描述:凡是文件名或文件内容包括关键字的文件都要找出来,这里要对文件名和文件内容创建索引。

2.1.3 获得原始文档

原始文档是指要索引和搜索的内容。原始内容包括互联网上的网页、数据库中的数据、磁盘上的文件等。

2.1.4 创建文档对象

获取原始内容的目的是为了索引,在索引前需要将原始内容创建成文档(Document),文档中包括一个一个的域(Field),域中存储内容。
这里我们可以将磁盘上的一个文件当成一个document,Document中包括一些Field(file_name文件名称、file_path文件路径、file_size文件大小、file_content文件内容),如下图:
在这里插入图片描述

注意:每个Document可以有多个Field,不同的Document可以有不同的Field,同一个Document可以有相同的Field(域名和域值都相同)

每个文档都有一个唯一的编号,就是文档id。

2.1.5 分析文档

将原始内容创建为包含域(Field)的文档(document),需要再对域中的内容进行分析,分析的过程是经过对原始文档提取单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个一个的单词。
比如下边的文档经过分析如下:
原文档内容:
Lucene is a Java full-text search engine. Lucene is not a complete
application, but rather a code library and API that can easily be used
to add search capabilities to applications.

分析后得到的语汇单元:
lucene、java、full、search、engine。。。。

每个单词叫做一个Term,不同的域中拆分出来的相同的单词是不同的term。term中包含两部分一部分是文档的域名,另一部分是单词的内容。
例如:文件名中包含apache和文件内容中包含的apache是不同的term。

2.1.6 创建索引

对所有文档分析得出的语汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单元从而找到Document(文档)。
在这里插入图片描述

注意:创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构。
传统方法是根据文件找到该文件的内容,在文件内容中匹配搜索关键字,这种方法是顺序扫描方法,数据量大、搜索慢。
倒排索引结构是根据内容(词语)找文档,如下图:
在这里插入图片描述

倒排索引结构也叫反向索引结构,包括索引和文档两部分,索引即词汇表,它的规模较小,而文档集合较大。

2.1.7 查询索引

查询索引也是搜索的过程。搜索就是用户输入关键字,从索引(index)中进行搜索的过程。根据关键字搜索索引,根据索引找到对应的文档,从而找到要搜索的内容(这里指磁盘上的文件)。

2.1.7.1 用户接口查询

全文检索系统提供用户搜索的界面供用户提交搜索的关键字,搜索完成展示搜索结果。
在这里插入图片描述
比如:

Lucene不提供制作用户搜索界面的功能,需要根据自己的需求开发搜索界面。

2.1.7.2 创建查询

用户输入查询关键字执行搜索之前需要先构建一个查询对象,查询对象中可以指定查询要搜索的Field文档域、查询关键字等,查询对象会生成具体的查询语法,
例如:
语法 “fileName:lucene”表示要搜索Field域的内容为“lucene”的文档

2.1.7.3 执行查询

搜索索引过程:
根据查询语法在倒排索引词典表中分别找出对应搜索词的索引,从而找到索引所链接的文档链表。
比如搜索语法为“fileName:lucene”表示搜索出fileName域中包含Lucene的文档。
搜索过程就是在索引上查找域为fileName,并且关键字为Lucene的term,并根据term找到文档id列表。
在这里插入图片描述

2.1.7.4 渲染结果

以一个友好的界面将查询结果展示给用户,用户根据搜索结果找自己想要的信息,为了帮助用户很快找到自己的结果,提供了很多展示的效果,比如搜索结果中将关键字高亮显示,百度提供的快照等。
在这里插入图片描述

2.3 分词

2.3.1 分词器的作用

a. 在创建索引的时候需要用到分词器,在使用字符串搜索的时候也会用到分词器,并且这两个地方要使用同一个分词器,否则可能会搜索不出来结果。

b. 分词器(Analyzer)的作用是把一段文本中的词按规则取出所包含的所有词,对应的是Analyzer类,这是一个抽象类(public abstract class org.apache.lucene.analysis.Analyzer),切分词的具体规则是由子类实现的,所以对于不同的语言规则,要有不同的分词器。

2.3.2 英文分词器的原理

a.英文的处理流程为:输入文本,词汇切分,词汇过滤(去除停用词),词干提取(形态还原)、大写转小写,结果输出。

b. 何为形态还原,意思是:去除单词词尾的形态变化,将其还原为词的原形,这样做可以搜索出更多有意义的结果,比如在搜索student的时候,同事也可以搜索出students的结果。

c. 任何一个分词法对英文的支持都是还可以的。

2.3.3 中文分词器的原理

a.中文分词比较复杂,并没有英文分词那么简单,这主要是因为中文的词与词之间并不是像英文那样用空格来隔开,

因为不是一个字就是一个词,而且一个词在另外一个地方就可能不是一个词,如:“我们是中国人”,"是中"就不是一个词,对于中文分词,通常有三种方式:单字分词、二分法分词、词典分词。

a.1 单字分词:就是按照中文一个字一个字的进行分词,比如:“我们是中国人”,分词的效果就是"我",“们”,“是”,“中”,“国”,“人”,StandardAnalyzer分词法就是单字分词。

a.2 二分法分词:按照两个字进行切分,比如:“我们是中国人”,分词的效果就是:“我们”,“们是”,“是中”,“中国”,“国人”,CJKAnalyzer分词法就是二分法分词

a.3 词库分词:按照某种算法构造词,然后去匹配已建好的词库集合,如果匹配到就切分出来成为词语,通常词库分词被认为是最好的中文分词算法,如:“我们是中国人”,分词的效果就是:“我们”,“中国人”,极易分词

MMAnalyzer、庖丁分词、IkAnalyzer等分词法就是属于词库分词。

b.分词器还有很大,请大家自行查询,它们的实现基本一致,都是Analyzer的子类,故而可以很完美的继承到Lucene中。

2.3.4 停用词的规则

有些词在文本中出现的频率非常高,但是对文本所携带的信息基本不产生影响,例如英文的"a、an、the、of"或中文的"的、了、着、是",以及各种标点符号等,这样的词称为停用词,文本经过分词处理后,停用词通常会被过滤掉,不会被进行索引,在检索的时候,用户的查询中如果含有停用词,检索系统也会将其过滤掉,这是因为用户输入哦查询字符串也要进行分词处理,排除停用词可以硷蒉建立索引的速度,减小索引库文件的大小。

2.3.5 常用的分词器

WhitespaceAnalyzer

仅仅是去掉了空格,没有其他任何操作,不支持中文。

SimpleAnalyzer

讲除了字母以外的符号全部去除,并且讲所有字符变为小写,需要注意的是这个分词器同样把数据也去除了,同样不支持中文。

StopAnalyzer

这个和SimpleAnalyzer类似,不过比他增加了一个的是,在其基础上还去除了所谓的stop words,比如the, a, this这些。这个也是不支持中文的。

StandardAnalyzer

英文方面的处理和StopAnalyzer一样的,对中文支持,使用的是单字切割。

CJKAnalyzer

这个支持中日韩,前三个字母也就是这三个国家的缩写。这个对于中文基本上不怎么用吧,对中文的支持很烂,它是用每两个字作为分割,分割方式个人感觉比较奇葩,我会在下面比较举例。

SmartChineseAnalyzer

中文的分词。比较标准的中文分词,对一些搜索处理的并不是很好。

IKAnalyzer

中国人自己开发,对于中文分词比较精准

2.3.6 IK 分词器

Elasticsearch中文分词我们采用Ik分词,ik有两种分词模式,ik_max_word,和ik_smart模式;

ik_max_word 和 ik_smart 什么区别?

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

索引时,为了提供索引的覆盖范围,通常会采用ik_max_word分析器,会以最细粒度分词索引,搜索时为了提高搜索准确度,会采用ik_smart分析器,会以粗粒度分词

我们可以使用网上的一些工具来查看分词的效果,比如https://www.sojson.com/analyzer
在这里插入图片描述

2.4 lucene全文检索与数据库查询的比较

2.4.1 性能上

**数据库:**比如我要查找某个商品,根据商品名,比如select * from product where doctname like %keywords%,这样查询的话对于数据量少是可以的,可是一旦你的数据量巨大几万几十万的时候,你的性能将会极大的减弱。

lucene: 全文检索,建立一个索引库,一次建立多次使用。在索引库里面会把所有的商品名根据分词器建立索引,就好比新华字典,索引对应document,比如输入衬衫,那么就会根据索引迅速的翻到衬衫对应的商品名,时间迅速,性能很好。

2.4.2 相关度排序

**数据库:**数据库要实现该功能也是可以的,可是需要改变表的结构,添加一个字段,然后该字段用于排名,最后查询的时候order by 一下

lucene: 查询出来的document都有一个算法(得分),根据算法可以计算得分,得分越高的排名越靠前,比如百度搜索一个东西,一般排名靠前的得分越高,得分通过算法,可以人工控制,比如百度推广,企业给的钱多得分自然高,因此排名靠前

2.4.3 准确性

**数据库:**select * from product where doctname like %ant%,搜索出来的可以是plant,aplant,planting等等,准确性不高

**lucene:**它是通过索引查询的,就好像你查字典一样,准确性比数据库的模糊查询高许多

完整代码:https://github.com/chutianmen/elasticsearch-examples

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值