遇到的问题

通过前面的学习,我们已经可以使用elasticsearch来进行数据的搜索了,但此时我们发现了一个问题,这个问题如果没有解决好就很影响我们后续的使用,那么该问题是什么呢?我们来看一下:

上面的截图是我搜索“在”关键字出来的结果,按照正常情况下,我们是不是不应该搜索“在”也出来结果呢?因为我们做的是搜索,不是模糊查询,既然是搜索的话,那像这种没有意义的关键字就不应该搜索出来才对的,还有像类似“在”、“是”、“了”等等这些单独存在不能构成一个中文词义的字符也可以搜索了,这显然是一种搜索效果不好的方式。还有一个问题,我们看看下面的截图:

上面这个截图是我搜索“中国人”这个关键词出来的结果,然后我们通过高亮匹配的内容发现,它是“中”、“国”、“人”拆成3个关键字去匹配内容了,而我们想要的是它匹配“中国人”,“中国”,“人”这样的搜索效果,但现在的情况却是每个中文字符都能搜索,这样就不太智能了。
那从表面上看,出现以上两个问题的原因貌似是因为elasticsearch对中文的分词不太智能,它现在的分词只是简单的安照每个中文字符来分,那如果我们想让elasticsearch的搜索能更智能一点,分析出我们搜索的关键字是否有含义,然后只搜这些有含义的词语,比如“中国人”,“中国”,“人”,这样的话我们要做什么操作才能让elasticsearch支持呢?这个就是我们接下来要探讨的问题了。
其实这个问题对elasticsearch来说是很好解决的,我们只需要换一个分词算法就可以了,但是为了让大家对elasticsearch的搜索过程和底层的分词原理有一个比较深刻的了解,我们不忙着切换其他分词算法,而是先来看看全文检索的一些基础知识,不然的话大家也仅仅只停留在会用的阶段,都不知道它底层做了什么事情。

数据类型

在详细了解全文搜索前,我们先来看看平时我们开发一个应用会遇到什么样的数据,这些数据是属于什么类型的,通过对这些数据的了解,我们接下来才能知道全文搜索,搜索的是什么样的数据。
在开发过程中通常都会接触到3种数据类型:结构化数据、半结构化数据和非结构化数据,这3种数据有什么特点呢?
1、结构化数据:是一种二维结构的数据,也就是说它的数据看上去是一个横向和纵向组成的,横向数据每一行都代表着一个实体的信息,纵向的列是固定的,并需要事先确定下来,是用来描述该实体的属性,所以每一行数据对应的属性都是一样的。结构化数据可以使用关系形数据库来储存,比如我们很熟悉的mysql,oracle等。如下图所示的数据:

2、半结构化数据:这种数据类型其实也是结构化的数据,但是不能使用关系型数据库来存储和描述数据,因为它每个实体的属性可以不一样,比如我们描述一个人的实体信息,其中一个人可以不描述年龄,一个人可以描述年龄,而存储在关系型数据库中的数据每个实体信息的属性都是需要一样的,但是它的扩展性很好,也比纯结构化数据灵活。我们经常使用的json、xml、yml就是半结构化数据。如下图所示的数据:

3、非结构化数据:跟结构化数据相对应的一种数据,他没有固定的结构,也就说我们不需要为该数据事先定义纵向的属性列。比如各种文档、图片、视频/音频等。而接下来我们要讲的全文搜索,就是搜索这种非结构化的数据。

创建索引过程

通过刚刚我们对数据类型的讲解,我们知道,全文搜索是搜索类似文档这种非结构化数据,并且它们的数据量都会比较大,那这样的话,如果我们按照传统的思维来对这些文档搜索的话,那肯定是搜索的速度会很慢,因为它要对这些文档逐字逐字的扫描,就好比我们看一本书,如果这本书没有目录的话,那么我们要找一个内容,就要在茫茫字海中寻找,那这样的话,我们是否可以把这些内容归纳成一个一个章节,这些章节有对应的页码,并统一放到一个地方,我们想要找某个内容的时候,先找这个内容对应的章节,再找到该章节对应的页面,这样的话就极大的提高了我们寻找内容的速度了,而这些归纳出来的章节就是我们所说的目录。
那别人在做全文搜索的时候,是否也能按照类似书的目录这种思想来来设计呢?答案是肯定的,但是大家要知道,这是一种思想,具体的实现细节有很多,我们来看看全文搜索的一种很常用的实现,具体过程如下:

1、给文档分词

首先,搜索引擎会有个分词组件,我们新建的文档会传给分词组件,然后分词组件根据它特定的分词算法,把文档拆分成一个一个的词元,如果以elasticsearch默认的分词算法来举例,那么如果我们创建以下这个文档:“我是一个中国人,张姓在中国是大姓。”,首先传到分词组件,然后得到以下新的数据:

我
是
一
个
中
国
人
张
姓
在
中
国
是
大
姓

这些就是分词组件拿到文档后拆分出来的词元集合。

2、将得到的词元创建索引

通过分词组件把文档拆成词元后,搜索引擎会把这些词元传给索引组件,索引组件会做以下事情:
(1)利用得到的词创建一个字典。
索引组件首先会使用刚刚新建文档得到的词元放到字典中,如下图所示:

该字典会有对应的文档ID

(2)对字典排序
对这些词进行排序,这里的排序算法就以中文拼音首字母顺序为例:

(3)合并相同的词
排好序后,会合并相同的词:

Frequency为词频率,表示此文档中包含了几个此词。

(4)生成索引文件
最后对排序并合并好的字典生成索引文件,该索引文件是一个倒排表,链表状的数据结构,每个词都会标记总共有多少文档包含此词,并且会关联着该词所在的文档id,文档id又会包含着此文档中包含了几个此词。
Document Frequency 即为文档频次,表示总共有多少文档包含此词。

如果此时我们再新增一个文档,那么该索引文件会发生什么变化呢?我们来看一下:添加“中国是全球人口最多的国家”
此时,搜索引擎又开始执行创建索引的步骤,经过1-4的步骤后,索引文件变成如下这样:

那么索引引擎在新增一个文档的时候就要做这些事情了,最后生成出这些倒排表结构的索引文件,每个词都会关联着所有包含该词的文档id,找到指定的词,就相当于找到该词对应的文档了。
但是我们通过上述的这些步骤发现,添加一个文档要做的事情还挺多的,那这样岂不是降低了我们系统的性能?如果单单从这方面来看,确实是,但是大家要知道,一般来说,我们录入一个需要做全文索引的数据,一般都是采用异步的方式去给该数据创建索引的,也就是说我们会发一个消息告诉专门创建索引的服务,并把相关的数据放到消息体,整个发送消息、获取消息和创建索引的过程都是异步的。业务系统本身只是发了个消息,然后就接着做下面的业务,真正耗性能的创建索引过程由搜索服务器处理,而搜素服务器要做集群太简单了,所以这点性能的消耗并不是什么问题。
最重要的是,有了这个索引文件,我们要搜索就变得很简单了,我们不需要在这些文档中扫描我们要找的内容了,而是查找索引文件就可以了。那接下来,我们来看看我们在输入一个关键字后,是如何在索引文件查找内容的。

搜索过程

从我们输入要搜索的关键字到返回搜索结果这个过程一般要经过这几个步骤:

1、给搜索关键字分词

首先还是使用分词组件给搜索关键字分词,比如用户输入“舌尖上的中国”,那么经过分词组件拆出来的词就有:

舌
尖
上
的
中
国

2、搜索索引

接着搜索引擎拿着这些拆出来的词去索引文件找对应的词,由于索引文件是有顺序的,一旦找到就停止向下找,然后获取该词对应的整个文档链表,如下图:

搜索出来的结果有“的”,“中”,“国”,并且后面带着该词所在的文档id链表。“的”有一个id为2的文档,“中”和“国”分别都有id为1和id为2这两个文档。但是由于“舌尖上”在索引文件中没有找到,所以也就没有搜索结果了。

3、链表合并

对包含“的”,“中”,“国”的链表进行合并操作,得到包含这些词的所有文档id,所以最终就得到id为1和2这两个文档了。最后进行搜索结果相关度排序,使用特定的相关度排序算法,根据词在文档出现的频率和我们提交的排序条件等计算,最终把这些文档id排序,排序好后默认获取前10条文档id,如果用户有提交查询数量,那么就获取用户提交的数量,最后通过文档id查询出整个文档返回给用户。

后记

那么这就是elasticsearch为我们提供搜索服务时,它要做的事情了,了解了这些大致的过程有利于我们更好的使用搜索引擎,并扩展一些基础知识。那么现在我们回到最开始说的遇到的问题上,我们说elasticsearch不够智能,它只是简单的按照一个一个字符去搜索文档的内容,导致没有语义的字符也搜索出结果了。那这个问题,我们通过上面的全文搜索过程可以知道,问题是出在分词这一块,也就是说分词的时候它是一个一个字符串去分的,最终导致索引文件保存的是文档中所有词。
那这个问题如何解决呢?elasticsearch是否提供其他的分词算法,让它支持中文语义来分词,这样的话,保存在索引文件中的词就不再是一个一个的字符,而是有意义的词语,比如“我是一个中国人,张姓在中国是大姓。”这个文档,就变成了这样:

是一个
中国
中国人
人
张姓

那我们下一章就来了解一下elasticsearch的分词组件,看看它给我们提供了哪些分词组件,和这些分词组件的特点是怎么样的,从而来确定elasticsearch是否内置一个更智能的中文分词方式。

Elasticsearch(六)了解全文搜索相关推荐

  1. springboot+springdata+elasticsearch+logstash+拼音分词实现全文搜索

    elasticsearch安装 下载地址:https://www.elastic.co/downloads/elasticsearch 解压到d盘software目录下 CMD下:cd D:\soft ...

  2. 全文搜索 Elasticsearch+analysis-ik

    前言 近期想尝试使用 Elasticsearch + analysis-ik 组合来实现全文搜索,所以需要在自己的Linux服务器上安装Java1.8的环境. 安装Java1.8 使用 yum sea ...

  3. 使用ElasticSearch进行文档搜索

    1.ElasticSearch 概念特点 全文搜索是对非结构化数据的一种搜索方式,所谓非结构化数据是指相对于结构化数据(如数据库)来说长度不固定或无固定格式的数据,例如文档.邮件等. 对非结构化数据的 ...

  4. Flask 教程 第十六章:全文搜索

    本文转载自:https://www.jianshu.com/p/56cfc972d372 这是Flask Mega-Tutorial系列的第十六部分,我将在其中为Microblog添加全文搜索功能. ...

  5. 微服务商城系统(六)商品搜索 SpringBoot 整合 Elasticsearch

    文章目录 一.Elasticsearch 和 IK 分词器的安装 二.Kibana 使用 三.数据导入 Elasticsearch 1.SpringData Elasticsearch 介绍 2.搜索 ...

  6. ElasticSearch中全文搜索(单词搜索、多次搜索、组合搜索和权重搜索)

    全文搜索两个最重要的方面是: 相关性(Relevance) 它是评价查询与其结果间的相关程度,并根据这种相关程度对结果排名的一种能力,这种计算方式可以是 TF/IDF 方法.地理位置邻近.模糊相似,或 ...

  7. elasticsearch全文搜索

    全文搜索 全文搜索两个最重要的方面是: 相关性(Relevance) 它是评价查询与其结果间的相关程度,并根据这种相关程度对结果排名的一种能力,这种计算方式可以是 TF/IDF 方法.地理位置邻近.模 ...

  8. python elasticsearch 入门教程(二) ---全文搜索

    python elasticsearch 入门教程(二) ---全文搜索 截止目前的搜索相对都很简单:单个姓名,通过年龄过滤.现在尝试下稍微高级点儿的全文搜索--一项 传统数据库确实很难搞定的任务. ...

  9. 全文搜索!收藏这篇Solr ElasticSearch 长文就可以搞定

    转载自  全文搜索!收藏这篇Solr ElasticSearch 长文就可以搞定 摘自:JaJian`博кē Java后端技术编者说:文章从浅到深,描述了什么是全文搜索,为什么要使用全文搜索,Solr ...

最新文章

  1. 【数据结构与算法】之给Nx3网格图涂色的方案数的求解算法
  2. windows病毒和linux吗,与Windows相比,Linux很少感染病毒。()
  3. windows 安装metis_Eigen+suitesparse for windows 安装
  4. html中怎么获取搜索框中的值,百度API 搜索框,获取相应的地点的uid
  5. leetcode 665. 非递减数列(贪心算法)
  6. 系统权限控制设计001---RBAC用户角色权限设计方案
  7. xampp的mysql和phpnow的mysql,xampp的apache和visualsvn的apache和phpnow的apache
  8. pip离线下载安装依赖包,及github包,及常用pip源
  9. 软件测试证书(1)— 软件评测师
  10. ps考证分数是用电脑改的吗
  11. ElementPlus 侧边栏右侧空隙
  12. 虚拟化操作系统ESXi 6.7安装配置详细步骤图文
  13. javascript实现div层移动的减速效果
  14. 数据集下载OTB,VOT,UAV,鸢尾花
  15. 天津大学大学计算机基础成绩查询,天津大学《大学计算机基础1》课程教学大纲.PDF...
  16. 图像内容修改—修改表格数字及文字
  17. Linux下使用游戏手柄
  18. 怎么回答TCP的三次握手问题
  19. DASH视频系统(服务器播放器)搭建
  20. 3Dmax云渲染是什么?

热门文章

  1. Excel饼图中既显示百分比
  2. 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 9 章 答案
  3. 干货技巧:10个冲压工艺及模架设计知识点
  4. 一个小蜜蜂游戏的源代码
  5. Springcloudalibaba整合es!实现相关性排序,集成完代码真香
  6. linux进程家族树,linux下用c语言创建进程树
  7. 电脑设置一键锁屏方法
  8. 计算机常用英语词汇及读音,100个最常用英文单词的完美发音,so easy!
  9. 16秋南开计算机应用答案,南开16秋学期“计算机应用基础”在线作业.doc
  10. 机器学习(9)--决策树和随机森林