Java基于Solr海量数据搜索,搜索引擎的实现( 二 )


举例
比如:我是北京海淀区中关村的中国人民 。
我们设置的词典是:北京、海淀区、中关村、中国、中国人民,那么根据词典组成的字典树如图所示:

Java基于Solr海量数据搜索,搜索引擎的实现

文章插图
 
然后我们根据这个字典树来对这段话进行词语切分 。IK分词器中,基本可以分为两种模式:一种是smart模式、一种是非smart模式,可以在代码中初始化的时候去配置 。
我们其实不用解释这两种模式的字面含义,直接打印两种模式的结果就可以看出来:
  • 原句:我是北京海淀区中关村的中国人民
  • smart模式:北京、海淀区、中关村、中国人民
  • 非smart模式:北京、海淀区、中关村、中国、中国人民
显而易见,非smart模式是将能够分出来的词全部输出;smart模式是根据内在的方法输出一个合理的分词结果,这就涉及到了歧义判断 。
举例
举个更有代表性的例子:张三说的确实在理 。
根据正向匹配可能的词元链:
  • L1:{张三,张,三}
  • L2:{说}
  • L3:{的确,的,确实,确,实在,实,在理,在,理}
首来看一下最基本的一些元素结构类:
public class Lexeme implements Comparable{……//词元的起始位移private int offset;//词元的相对起始位置private int begin;//词元的长度private int length;//词元文本private String lexemeText;//词元类型private int lexemeType;…… }这里的Lexeme(词元),可以理解为是一个词语或单词 。其中的begin,是指其在输入文本中的位置 。注意,它是实现Comparable的,起始位置靠前的优先,长度较长的优先,这可以用来决定一个词在一条分词结果的词元链中的位置,可以用于得到上面例子中分词结果中的各个词的顺序 。
/* * 词元在排序集合中的比较算法* @see JAVA.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Lexeme other) { //起始位置优先if(this.begin < other.getBegin()){return -1;}else if(this.begin == other.getBegin()){//词元长度优先if(this.length > other.getLength()){return -1;}else if(this.length == other.getLength()){return 0;}else {//this.length < other.getLength()return 1;}}else{//this.begin > other.getBegin()return 1;} }smart模式歧义消除算法:
  • 词元位置权重比较(词元长度积),含义是选取长的词元位置在后的集合
  • L31:{的,确实,在理}1*1+2*2+3*2=11
  • L32:{的确,实,在理} 1*2+2*1+3*2=10
  • L33:{的确,实在,理} 1*2+2*2+3*1=9
  • 最后的分词结果:张三,说,的,确实,在理
分词就介绍这么多,大家可以去读一下IK分词器的源码,深入地了解一下,源码地址:https://github.com/quentinxxz/Search/tree/master/IKAnalyzer2012FF_hf1_source/
三、倒排索引算法
3.1 介绍
我们可以把倒排索引算法想象成查字典时的目录一样,我们知道需要查的字的目录后,就会很快地查找到 。如果用专业的语言解释的话就是:
倒排索引源于实际应用中需要根据属性的值来查找记录 。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址 。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index) 。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(inverted file) 。
倒排文件(倒排索引),索引对象是文档或者文档集合中的单词等,用来存储这些单词在一个文档或者一组文档中的存储位置,是对文档或者文档集合的一种最常用的索引机制 。
搜索引擎的关键步骤就是建立倒排索引,倒排索引一般表示为一个关键词,然后是它的频度(出现的次数),位置(出现在哪一篇文章或网页中,及有关的日期,作者等信息),它相当于为互联网上几千亿页网页做了一个索引,好比一本书的目录、标签一般 。读者想看哪一个主题相关的章节,直接根据目录即可找到相关的页面 。不必再从书的第一页到最后一页,一页一页地查找 。
【Java基于Solr海量数据搜索,搜索引擎的实现】3.2 Lucene倒排索引原理
Lucerne是一个开放源代码的高性能的基于java的全文检索引擎工具包,不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎 。目的是为软件开发人员提供一个简单易用的工具包,以方便在目标系统中实现全文检索的功能,或者以此为基础建立起完整的全文检索引擎 。
假设有两篇文章1和2:


推荐阅读