Hello,欢迎来到程序员社区。 今天聊一聊 Lucene 查询索引库,希望对大家有所帮助。
Java面试手册PDF下载:http://117.78.51.75/219-2
以后用的分词库为IKAnalyzer中文分词库。
查询
说明:这是QueryParser的继承结构,在这里我们用的是MultiFieldQueryParser.这个类的好处可以选择多个属性进行查询。而QueryParser只能选择一个。
分页
先创建出数据:
读取数据看看是否创建成功:
说明:
1) 在全文检索系统中,一般查询出来的内容比较多,所以必须将查询出来的内容进行分页处理。
2) 原理同hibernate的分页查询。在hibernate的分页查询中,有两个参数:
int firstResult 当前页的第一行在数据库里的行数
int maxResult 每页显示的页数
搜索方式
使用查询字符串
QueryParser->Query对象
可以使用查询条件
“lucene AND 互联网” 都出现符合查询条件
“lucene OR 互联网” 只要出现其一就符合查询条件
自己创建与配置Query对象
关键词查询(TermQuery)
注:因为保存引索的时候是通过分词器保存,所以所有的因为在索引
库里都为小写,所以lucene必须得小写,不然查询不到。如果使用
查询字符串进行查询,对应的语法格式为:title:lucene
查询所有文档
如果使用查询字符串,对应语法:*:*
范围查询
如果使用查询字符串,
第一个: id:[5 TO 15]
第二个: id:{5 TO 15}
注:在lucene中,处理数字是不能直接写入的,要进行转化。NumberStringTools帮助类给出了转化工具:
在工具类DocumentUtils中也做相应的转化:
通配符查询
如果使用查询字符串:tit编程电子书汇总le:lucen?
短语查询
上面的0代表第0个位置
上面的1代表第3个位置
使用查询字符串:title:”lucene ? ? 互联网”
Boolean查询
可以把多个查询条件组合成一个查询条件
如图为:同时满足title中有lucene关键字和ID为5到15的所有索引数据。不包括5和15
使用查询字符串:+id:{5 TO 15} +title:lucene
注意:
1、 单独使用MUST_NOT 没有意义
2、 MUST_NOT和MUST_NOT 无意义,检索无结果
3、单独使用SHOULD:结果相当于MUST
4、SHOULD和MUST_NOT: 此时SHOULD相当于MUST,结果同MUST和MUST_NOT
5、MUST和SHOULD:此时SHOULD无意义,结果为MUST子句的检索结果
过滤
利用indexSearch.search的重载函数的过滤器参数实现对结果的过滤。从这里可以看出这是一个范围过滤器。第二个参数与第三个参数为5,15。但是luce编程电子书汇总ne会把这两个参数当作字符串来对待。所以这样搜索结果为0。
进行如下处理:
凡是数字类型的都必须经过这样的方式进行处理。
凡是日期类型的都必须经过这样的方式进行处理。这样才能保证结果的正确性。
排序
相关度得分
实验一:
在索引库中内容完全相同的情况下,用几个关键词搜索,看是否得分相同。
结果:
同一个关键词得分对于所有的Document是一样的。但是不同的关键词的分数不一样。关键词和文本内容匹配越多,得分越高。也就是相关度得分就高
实验二:
再插入一个Document,在其中的content中增加一个关键词,然后保存到索引库中。如图:
在content中,google的后面又加了一个词”互联网”。然后再进行搜索,这个时候,id为26的被排到了第一位。相关度得分最高。因为其他的Document在content中匹配”互联网”只有一处,而id为26的有两处。
结果:
同一个关键词如果在所有匹配的文本中的相关度得分不一样,按照相关度得分从高到低的顺序排列。
实验三:
如果想从百度上排名第一,就得控制相关度得分。在lucene中,可以人为控制相关度得分。如图:
利用Document.setBoost可以控制得分。默认值为1
结论:
利用Document.setBoost可以人为控制相关度得分,从而把某一个引索内容排到最前面。
按照某个字段进行排序
如图所示的代码,重载了indexSearcher.search方法。在这个方法中,Sort对 象就是指定的按照id升序排列。SortField.INT指定了ID的类型。类型不一样,大小的比较就不一样。
上面代码查询出来以后是按照id的升序排列。
这个代码为按照id的降序排列。其中最后一个参数为reverse
Reverse为false 升序(默认)
Reverse 为true 降序
注:按照某个字段进行排序与相关度得分没有关系。
高亮
高亮的作用
1) 使关键字的颜色和其他字的颜色不一样,这样关键字就比较突出。
方法:在关键字周围加上前缀和后缀
font color=’red’>中国font>
2) 生成摘要(从关键词出现最多的地方截取一段文本),可以配置要截取文本的字符数量。
编程步骤
/**
* 高亮
* * 使关键字变色
* * 设置
* * 使用
* * 控制摘要的大小
* @author AdminiJava面试手册strator
*/
public class HighlighterTest {
@Test
Java面试手册public void testSearchIndex() throws Exception{
IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.directory);
QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_30, new String[]{"title","content"}, LuceneUtils.analyzer);
Query query = queryParser.parse("Lucene");
TopDocs topDocs = indexSearcher.search(query, 25);
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
/***********************************************************************/
/**
* 给关键字加上前缀和后缀
*/
Formatter formatter = new SimpleHTMLFormatter("","");
/**
* scorer封装了关键字
*/
Scorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter,scorer);
/**
* 创建一个摘要
*/
Fragmenter fragmenter = new SimpleFragmenter(10);
highlighter.setTextFragmenter(fragmenter);
/***********************************************************************/
List articleList = new ArrayList();
for(ScoreDoc scoreDoc:scoreDocs){
float score = scoreDoc.score;
System.out.println(score);//相关的得分
Document document = indexSearcher.doc(scoreDoc.doc);
Article article = DocumentUtils.document2Article(document);
/*
* 使用高亮器
*/
/**
* 1、分词器
* 查找关键词
* 2、字段
* 在哪个字段上进行高亮
* 3、字段的内容
* 把字段的内容提取出来
*/
String titleText = highlighter.getBestFragment(LuceneUtils.analyzer, "title", document.get("title"));
String contentText = highlighter.getBestFragment(LuceneUtils.analyzer, "content", document.get("content"));
if(titleText!=null){
article.setTitle(titleText);
}
if(contentText!=null){
article.setContent(contentText);
}
articleList.add(article);
}
for(Article article:articleList){
System.out.println(article.getId());
System.out.println(article.getTitle());
System.out.println(article.getContent());
}
}
}
创建和配置高量器
一个高亮器的创建需要两个条件:
Formatter 要把关键词显示成什么样子
Scorer 查询条件
Fragmenter设置文本的长度。默认为100。
如果文本的内容长度超过所设定的大小,超过的部分将显示不出来。
使用高亮器
getBestFragment为得到高亮后的文本。
参数:
-
分词器
如果是英文:StandardAnalyzer 如果是中文:IKAnalyzer
-
在哪个属性上进行高亮
- 要高亮的内容
时间不一定能证明很多东西,但是一定能看透很多东西。坚信自己的选择,不动摇,使劲跑,明天会更好。