一、Lucene是什么
Lucene 是一个高效的,基于Java 的全文检索库
我们先学习下全文检索,什么叫做全文检索呢?这要从我们生活中的数据说起。生活中的数据总体分为两种:结构化数据 和非结构化数据
结构化数据: 指具有固定格式或有限长度的数据,如数据库,元数据等。
非结构化数据: 指不定长或无固定格式的数据,如邮件,word文档等。
有的地方还会提到第三种,半结构化数据,如XML,HTML等,根据需要可按结构化数据来处理,也可抽取出纯文本按非结构化数据来处理。
非结构化数据又一种叫法叫全文数据。
1 lucene.net全文检索简介
2 lucene.net七大对象介绍和多种query方式
3 lucene索引建立和查询DEMO
4 索引增删改查和分词处理
1.Lucene.net全文检索简介 lucene.net:全文检索的工具包,不是应用,只是个类库,完成了全文检索的功能 lucene是全文搜索必备的,是大型系统必备的 这个工具包的使用原理 是把数据拆分(Analysis–分词器)—存起来—查询时—拆分—匹配—结果
2. Lucene.net七大对象
Analysis–分词器,负责把字符串拆分成原子,包含了标准分词,直接空格拆分。项目中用的是盘古中文分词
Document–数据结构,定义存储数据的格式 存储单位,每条数据就是一个Document 每个字段是一个field
Index–索引的读写类 索引的读出/写入 IndexReader IndexWriter
QueryParser–查询解析器,负责解析查询语句 得到query对象
Search—负责各种查询类,命令解析后得到就是查询类
Store—索引存储类,负责文件夹等等
Util—常见工具类库
多种Query方式
Search:
/// TermQuery–单元查询 new Term(“title”,“张三”) title:张三
/// BoolenQuery—new Term(“title”,“张三”) and new Term(“title”,“李四”) title:张三 + title:李四 /// new Term(“title”,“张三”) or new Term(“title”,“李四”) title:张三 title:李四 多个query
/// WildcardQuery—带占位符 通配符 new Term(“title”,“张?”) title:张? /// new Term(“title”,“张*”) title:张*
/// PrefixQuery—前缀查询 以xx开头 title:张*
/// PhraseQuery—间隔距离 可以查询包含a和b,而且a和b距离不超过5 包含没有 包含提莫 而且二者距离不能超过5 title: “没有 提莫”~5 没有蘑菇的提莫 没有蘑菇的蘑菇的蘑菇的提莫
/// FuzzyQuery—近似查询,ibhone----iphone title:ibhone~
/// RangeQuery—范围查询 []闭区间 {}开区间 [1,100] {1,100} ///
/// Lucene.Net一进一出,建立索引需要获取数据源,分词-保存到硬盘
/// 索引查找,
/// 自然会有些延迟,以前淘宝上架宝贝,第二天才能搜索的
/// 索引更新策略:1 数据更新—丢一个队列—一个processor通过队列完成更新
/// 2 每一周全部索引一遍
/// lucene索引存的是原子–docid1,docid2,docid3
/// 不store可以大量节约空间;查找时原子匹配多个id;
/// 针对京东数据建立索引和查询接口
全文检索大体分两个过程,索引创建(Indexing)和搜索索引(Search)
索引创建:将现实世界中所有的结构化和非结构化数据提取信息,创建索引的过程。
搜索索引:就是得到用户的查询请求,搜索创建的索引,然后返回结果的过程。
于是全文检索就存在三个重要问题:
3. 索引里面究竟存些什么?(Index)
4. 如何创建索引?(Indexing)
5. 如何对索引进行搜索?(Search)
下面来对每个问题进行研究。
一、索引里究竟存些什么
索引里面究竟存些什么呢?
首先来看为什么顺序扫描的速度慢:
其实是我们想要搜索的信息和非结构化数据中所存储的信息不一致造成的。
非结构化数据中所存储的信息是每个文件包含哪些字符串,也即已知文件,想求字符串相对容易,也即是从文件到字符串的映射。而我们想搜索的信息是哪些文件包含此字符串,即已知字符串,欲求文件,也即从字符串到文件的映射。两者恰恰相反。如果索引总能够保存从字符串到文件的映射,则会大大提高搜索速度。
由于从字符串到文件的映射是文件到字符串映射的反向过程,于是保存这种信息的索引称为反向索引。反向索引保存的信息如下:
假设我的文档集合里面有100篇文档,为了方便表示,我们为文档编号从1到100,得到下面的结构
两者还是有区别的,顺序扫描是每次都要扫描,而创建索引的过程仅仅需要一次,每次搜索,创建索引的过程不必经过,仅仅搜索创建好的索引就可以。
这也是全文搜索相对于顺序扫描的优势之一:一次索引,多次使用
二、如何创建索引
全文检索的索引创建过程一般有以下几步:
第一步:一些要索引的原文档(Document)。
为了说明索引创建过程,这里用两个文件为例:
文件一:Students should be allowed to go out with their friends, but not allowed to drink beer.
文件二:My friend Jerry went to school to see his students but found them drunk which is not allowed.
第二步:将原文档传给分词器(Tokenizer)。
分词器(Tokenizer)会做以下几件事情( 此过程称为Tokenize) :
6. 将文档分成一个一个单独的单词。
7. 去除标点符号。
8. 去除停词(Stop word) 。
所谓停词(Stop word)就是一种语言中最普通的一些单词,由于没有特别的意义,因而大多数情况下不能成为搜索的关键词,因而创建索引时,这种词会被去掉而减少索引的大小。
英语中停词(Stop word)如:“the”,“a”,“this”等。
对于每一种语言的分词组件(Tokenizer),都有一个停词(stop word)集合。
经过分词(Tokenizer) 后得到的结果称为词元(Token)
第三步:将得到的词元(Token)传给语言处理组件(Linguistic Processor)
第四步:将得到的词(Term)传给索引组件(Indexer)。
索引组件(Indexer)主要做以下几件事情:
9. 利用得到的词(Term)创建一个字典
- 索引过程:
1) 有一系列被索引文件
2) 被索引文件经过语法分析和语言处理形成一系列词(Term) 。
3) 经过索引创建形成词典和反向索引表。
4) 通过索引存储将索引写入硬盘。 - 搜索过程:
a) 用户输入查询语句。
b) 对查询语句经过语法分析和语言分析得到一系列词(Term) 。
c) 通过语法分析得到一个查询树。
d) 通过索引存储将索引读入到内存。
e) 利用查询树搜索索引,从而得到每个词(Term) 的文档链表,对文档链表进行交,差,并得到结果文档
f) 将搜索到的结果文档对查询的相关性进行排序。
g) 返回查询结果给用户
https://blog.csdn.net/u014209975/article/details/53263642