最近项目中需要用到solr,正好回味一下。
1.结构化数据和非结构化数据
结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。
非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等磁盘上的文件。
1.1非结构化数据的查询方法
(1)顺序扫描法
比如要搜索摸个数据,会从头到尾去搜索。数据库中的like也是这个原理。
优点: 如果文档中存在要找的关键字就一定能找到想要的内容。
缺点: 慢, 效率低。
(2)全文检索算法(倒排索引算法)
将文件中的内容提取出来, 将文字拆封成一个一个的词(分词), 将这些词组成索引(字典中的目录), 搜索的时候先搜索索引,通过索引找文档,这个过程就叫做全文检索.。
优点: 搜索速度快。
缺点: 因为创建的索引需要占用磁盘空间,所以这个算法会使用掉更多的磁盘空间,这是用空间换时间。
2.Lucene
Lucene是apache下的一个开放源代码的全文检索引擎工具包。
Lucene4.10.3要求Jdk1.7以上。
2.1Lucene结构
2.2Lucene是如何实现全文检索的
2.2.1索引和搜索流程图
1、绿色表示索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括:
确定原始内容即要搜索的内容à采集文档à创建文档à分析文档à索引文档
2、红色表示搜索过程,从索引库中搜索内容,搜索过程包括:
用户通过搜索界面创建查询,执行搜索,从索引库搜索渲染搜索结果
2.2.2创建文档对象
在这之前要获取原始数据内容,获取原始内容的目的是为了索引,在索引前需要将原始内容创建成文档(Document),文档中包括一个一个的域(Field),域中存储内容。
我们可以将磁盘上的一个文件当成一个document,Document中包括一些Field(file_name文件名称、file_path文件路径、file_size文件大小、file_content文件内容),如下图:
注意:每个Document可以有多个Field,不同的Document可以有不同的Field,同一个Document可以有相同的Field(域名和域值都相同)。
每个文档都有一个唯一的编号,就是文档id。
索引:就相当于是目录,存在显示为 域名:词, 它里面有指针执行这个词来源的文档。
索引库: 放索引的文件夹(这个文件夹可以自己随意创建,在里面放索引就是索引库),Term词元: 就是一个词, 是lucene中词的最小单位。
文档:用来存储数据的。
域:文档又分为了一个个的域,类似与key-value的结构。
2.2.3分析文档
将原始内容创建为包含域(Field)的文档(document),需要再对域中的内容进行分析,分析的过程是经过对原始文档提取单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个一个的单词。
比如下边的文档经过分析如下:
原文档内容:
Lucene is a Javafull-text search engine. Lucene is not acomplete
application, butrather a code library and API that can easily be used
to add searchcapabilities to applications.
分析后得到的语汇单元:
lucene、java、full、search、engine。。。。
每个单词叫做一个Term,不同的域中拆分出来的相同的单词是不同的term。term中包含两部分一部分是文档的域名,另一部分是单词的内容。
例如:文件名中包含apache和文件内容中包含的apache是不同的term。
2.2.4创建索引
对所有文档分析得出的语汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单元从而找到Document(文档)。
注意:创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构。
传统方法是根据文件找到该文件的内容,在文件内容中匹配搜索关键字,这种方法是顺序扫描方法,数据量大、搜索慢。
倒排索引结构是根据内容(词语)找文档,如下图:
倒排索引结构也叫反向索引结构,包括索引和文档两部分,索引即词汇表,它的规模较小,而文档集合较大。
2.2.5查询索引的过程
搜索索引过程:
1.根据查询语法在倒排索引词典表中分别找出对应搜索词的索引,从而找到索引所链接的文档链表。
比如搜索语法为“luceneAND java”表示搜索出的文档中即要包括lucene也要包括java。
2、由于是AND,所以要对包含lucene或java词语的链表进行交集,得到文档链表应该包括每一个搜索词语
3、获取文档中的Field域数据。
2.2.6渲染搜索结果
一般有关键字的高亮显示啊等等。