前几天投简历的时候在技能栏里写了一个熟练使用Lucene全文检索系统。
当年确实用Lucene全文检索系统写了一个唐诗检索系统(实现了分页,高亮)。
前台用EasyUI实现的不是太完美,但是可以勉强使用。github地址 有兴趣的可以去看看。
闲话不多说,下面简单说说Lucene
全文检索:
- 全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。
类似于:新华字典先通过汉字抽象出偏旁部首、拼音,然后通过偏旁部首、拼音快速查找汉字的过程
- 全文检索创建索引三部曲:需要检索的数据(Document)、分析器(Analyzer)、创建索引(index)
全文检索检索索引四部曲:关键词(Keyword)、分析器(Analyzer)、检索索引(Searcher)、返回结果(Results)
文件的结构
- 索引 index
- 段 segment
- 文档 document 相当与数据库中的一行数据 要被搜索这本篇文章叫做文档,一篇文章就叫一个文档
- 域 field 相当于一行数据中的一个字段 文章中的各个字段,比如标题、作者
- 词元 term 域分词后的最小单元
词元的权重
通过用户输入的关键字检索后的数据会根据权重来排序
term 在同一个文章中出现的次数越多越重要
term 在越多文章中出现 则该词元越不重要
Lucene常用功能
- 索引的创建
- 索引的检索
- 索引的修改
- 索引的删除
- 索引域加权(类似百度搜素中的竞价排名)
Lucene查询
常用Query查询:
TermQuery 词元检索
// 基于词元的检索
query = new TermQuery(new Term("name","aa"));
TermRangeQuery 词元范围检索
// 基于词元范围的检索 字符或者字母范围
// 参数一:检索域 参数二:起始字符 参数三:结束字符 参数四:是不是包含起始 参数五:是不是包含结束
query = new TermRangeQuery("name",new BytesRef("aa"),new BytesRef("ae"),false,false);
NumericRangeQuery 数字范围检索
// 基于数字范围的检索 id数字 1-5
// 参数一:检索域名 参数二:最小 参数三:最大 参数四:是不是包含最小 参数五:是不是包含最大
query = NumericRangeQuery.newIntRange("id",3,5,true,false);
PrefixQuery 前缀检索
// 基于前缀的检索 检索参数为term term中参数为检索域名 和 前缀
query = new PrefixQuery(new Term("name","a"));
WildcardQuery 通配查询
// 基于通配符的检索 ? 占位符一个字符 * 匹配零个或者多个字符
query = new WildcardQuery(new Term("name","?b"));
query = new WildcardQuery(new Term("name","*c"));
FuzzyQuery 模糊查询
// 基于模糊的检索 只要在一定误差范围内都可以检索到 符合条件内容和相似内容
query = new FuzzyQuery(new Term("name","az"));
query = new FuzzyQuery(new Term("content","一"));
BooleanQuery 布尔查询
// 多条件检索 检索id为1的文档 并且content内容有 “海” 文档
// BooleanClause.Occur.MUST 并
// BooleanClause.Occur.MUST_NOT 非
// BooleanClause.Occur.SHOULD 或 BooleanQuery booleanQuery = new BooleanQuery(); // name域中必须有aa
booleanQuery.add(new TermQuery(new Term("name","aa")),BooleanClause.Occur.MUST)
PhraseQuery 短语查询
// 基于短语的检索 应用于 英文短语查询 i am gaozhy,welcome to bejing
// 词与词的偏移量
query = new PhraseQuery(2,"content","一","三");