Lucene的多域查询、结果中查询、查询结果分页、高亮查询结果和结果评分
1.针对多个域的一次性查询
1.1.三种方案
- // 在这四个域中检索
- String[] fields = { "phoneType", "name", "category", "price" };
- Query query = new MultiFieldQueryParser(Version.LUCENE_36, fields, analyzer).parse(keyword);
第三种方法就是使用高级DisjunctionMaxQuery类,它会封装一个或者多个任意的查询,将匹配的文档进行OR操作。
1.2.方案选择
2.在结果中查询
2.1.两种方案
2.2.QueryFilter方案
- import org.apache.lucene.search.CachingWrapperFilter;
- import org.apache.lucene.search.Query;
- import org.apache.lucene.search.QueryWrapperFilter;
- public class QueryFilter extends CachingWrapperFilter {
- /**
- * Constructs a filter which only matches documents matching
- * <code>query</code>.
- */
- public QueryFilter(Query query) {
- super(new QueryWrapperFilter(query));
- }
- public boolean equals(Object o) {
- return super.equals((QueryFilter) o);
- }
- public int hashCode() {
- return super.hashCode() ^ 0x923F64B9;
- }
- }
- //简单实现对keyword的搜索
- public static void search(String keyword) throws IOException, ParseException {
- QueryParser queryParser = new QueryParser("content",new SimpleAnalyzer());
- Query query = queryParser.parse(keyword.trim());
- QueryFilter filter = new QueryFilter(query);
- //检索
- search(query, filter);
- }
- //在搜索oldKeyword的结果集中搜索newKeyword
- public static void searchInResult(String newKeyword, String oldKeyword) throws ParseException, IOException {
- QueryParser queryParser = new QueryParser("content",new SimpleAnalyzer());
- Query query = queryParser.parse(newKeyword.trim());
- Query oldQuery = queryParser.parse(oldKeyword.trim());
- QueryFilter oldFilter = new QueryFilter(oldQuery);
- CachingWrapperFilter filter = new CachingWrapperFilter(oldFilter);
- //检索
- search(query, filter);
- }
- private static void search(Query query, Filter filter) throws IOException, ParseException {
- IndexSearcher ins = new IndexSearcher("d:/tesindex");
- Hits hits = ins.search(query, filter);
- for (int i = 0; i < hits.length(); i++) {
- Document doc = hits.doc(i);
- System.out.println(doc.get("content"));
- }
- }
2.3.BooleanQuery方案
- //创建BooleanQuery
- BooleanQuery booleanQuery = new BooleanQuery();
- //多域检索,在这四个域中检索
- String[] fields = { "phoneType", "name", "category","free" };
- Query multiFieldQuery = new MultiFieldQueryParser(Version.LUCENE_36, fields, analyzer).parse(keyword);
- //将multiFieldQuery添加到BooleanQuery中
- booleanQuery.add(multiFieldQuery, BooleanClause.Occur.MUST);
- //如果osKeyword不为空
- if(osKeyword != null && !osKeyword.equals("") && !osKeyword.equals("null")){
- TermQuery osQuery = new TermQuery(new Term("phoneType",osKeyword));
- //将osQuery添加到BooleanQuery中
- booleanQuery.add(osQuery, BooleanClause.Occur.MUST);
- }
3.检索结果分页
3.1.两种方案
3.2.分页实现
- /**
- * 对搜索返回的前n条结果进行分页显示
- * @param keyWord 查询关键词
- * @param pageSize 每页显示记录数
- * @param currentPage 当前页
- */
- public void paginationQuery(String keyWord,int pageSize,int currentPage) throws ParseException, CorruptIndexException, IOException {
- String[] fields = {"title","content"};
- QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_36,fields,analyzer);
- Query query = queryParser.parse(keyWord);
- IndexReader indexReader = IndexReader.open(directory);
- IndexSearcher indexSearcher = new IndexSearcher(indexReader);
- //TopDocs 搜索返回的结果
- TopDocs topDocs = indexSearcher.search(query, 100);//只返回前100条记录
- int totalCount = topDocs.totalHits; // 搜索结果总数量
- ScoreDoc[] scoreDocs = topDocs.scoreDocs; // 搜索返回的结果集合
- //查询起始记录位置
- int begin = pageSize * (currentPage - 1) ;
- //查询终止记录位置
- int end = Math.min(begin + pageSize, scoreDocs.length);
- //进行分页查询
- for(int i=begin;i<end;i++) {
- int docID = scoreDocs[i].doc;
- Document doc = indexSearcher.doc(docID);
- int id = NumericUtils.prefixCodedToInt(doc.get("id"));
- String title = doc.get("title");
- System.out.println("id is : "+id);
- System.out.println("title is : "+title);
- }
- }
4.高亮检索结果
- public void search(String fieldName, String keyword)throws CorruptIndexException, IOException, ParseException {
- searcher = new IndexSearcher(indexPath);
- QueryParser queryParse = new QueryParser(fieldName, analyzer); // 构造QueryParser,解析用户输入的检索关键字
- Query query = queryParse.parse(keyword);
- Hits hits = searcher.search(query);
- for (int i = 0; i < hits.length(); i++) {
- Document doc = hits.doc(i);
- String text = doc.get(fieldName);
- SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
- Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));
- highlighter.setTextFragmenter(new SimpleFragmenter(text.length()));
- if (text != null) {
- TokenStream tokenStream = analyzer.tokenStream(fieldName,new StringReader(text));
- String highLightText = highlighter.getBestFragment(tokenStream,text);
- System.out.println("高亮显示第 " + (i + 1) + " 条检索结果如下所示:");
- System.out.println(highLightText);
- }
- }
- searcher.close();
- }
上文的一行判断语句很重要:if(text != null),如果text为空,那么显示结果不但没有被高亮,而且得到的原始结果也会被过滤。可以再代码中加上,如果text==null,则让将原始检索结果赋给text,从而将结果显示出来。
5.检索结果的评分
- //评分
- Explanation explanation = indexSearcher.explain(query, docID);
- System.out.println(explanation.toString());
在后台打印出来的信息如下:
- 2.4342022 = (MATCH) weight(name:books in 71491), product of:
- 0.2964393 = queryWeight(name:books), product of:
- 8.21147 = idf(docFreq=109, maxDocs=149037)
- 0.036100637 = queryNorm
Lucene的多域查询、结果中查询、查询结果分页、高亮查询结果和结果评分的更多相关文章
- TP 查询语句中如何使用 FIND_IN_SET 这样的查询方法
TP 查询语句中如何使用 FIND_IN_SET 这样的查询方法 $condition['_string'] = 'FIND_IN_SET('.$citys.',city)';
- SQLSERVER | 查询数据库中所有的表的名字 | 查询数据库中的所有数据库名
SQLSERVER 1.查询某个数据库中所有的表名: SELECT Name FROM SysObjects Where XType='U' ORDER BY Name 2.查询数据库中的所有数据库 ...
- JDBC在javaweb中的应用之分页数据查询
分页查询 分页查询是java web开发中经常使用到的技术.在数据库中数据量非常大的情况下,不适合将所有的数据全部显示到一个页面中,同时为了节约程序以及数据库的资源,就需要对数据进行分页查询操作. 通 ...
- 查询oracle中所有用户信息 禁用用户
----查询oracle中所有用户信息 ----1.查询数据库中的表空间名称 ----1)查询所有表空间 select tablespace_name from dba_tablespaces; se ...
- Lucene之模糊、精确、匹配、范围、多条件查询
Lucene的查询方式很 丰富,对于数值类型的数据,采取TermRangeQuery的方式,对于String类型的,就可以采取TermQuery等,查询方式了,可以通过采取合适的查询方式,检索到数据. ...
- MySQL的查询计划中ken_len的值计算
本文首先介绍了MySQL的查询计划中ken_len的含义:然后介绍了key_len的计算方法:最后通过一个伪造的例子,来说明如何通过key_len来查看联合索引有多少列被使用. key_len的含义 ...
- 如何用Excel直接查询Oracle中的数据
将Oracle中查询的数据保存为Excel文件,通常使用的是PL/SQL Developer. 其实,Excel可直接写SQL语句查询Oracle中数据,在这里,用到ODBC驱动.详细步骤如下: 一. ...
- Entity Framework 5中应用表值函数进行Linq查询
Entity Framework 5引入了表值函数(Table-Valued Functions TVFs).表值函数的返回类型是一个Table类型,可用在SQL查询语句中.最简单的表值函数,读取客户 ...
- C#中使用Sql对Excel条件查询
如何在C#中实现对Excel的条件查询呢? 在使用Sql条件语句对Excel进行查询时,遇到"至少一个参数没有被指定值"的问题,如何解决? 使用OleDbConnection对象创 ...
随机推荐
- 【转】WF4.0实战系列索引
转自:http://www.cnblogs.com/zhuqil/archive/2010/07/05/wf4-in-action-index.html 此系列的工作流文件案例比较多点,实用性好. W ...
- 【POJ3461】【KMP】Oulipo
Description The French author Georges Perec (1936–1982) once wrote a book, La disparition, without t ...
- CSS动画:Transform中使用频繁的scale,rotate,translate动画
动画中,skew只是transform中的一种形式的动画,我们还可以学习scale,rotate,translate.这是目前使用比较频繁的属性动作. 1.scale动画的定义:(单位数值) scal ...
- HTML5-黑客帝国2D
<!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>& ...
- 使用php实现爬虫程序 套取网站的图片实例
<?php //去采集a67 图片 网站链接 http://www.xiamov.com/list/1/p.2 你也可以采集其他网站的图片 //创建链接 dedecms--a67 //设置执行不 ...
- python 图片压缩存储
python(PIL)图像处理(等比例压缩.裁剪压缩) 缩略(水印)图 http://outofmemory.cn/code-snippet/12264/python-PIL-image-proces ...
- 如何让同一个字段在不同的view中显示不同的内容
many2one 字段默认显示 对象的name字段, 但也可以定义name_get方法显示不同的内容 如res.partner 对象可以根据 context 内容是否显示 客户的地址,职位,email ...
- JavaScript解析机制
JavaScript是一种解释型语言,按照<script>块儿来预编译和执行. JavaScript解释器在预编译阶段,先预声明变量,再预声明函数.在执行阶段,进行变量赋值,和函数执行. ...
- Kendo UI for Angular 2 控件
Kendo UI for Angular 2 控件 伴随着 Angular 2 的正式 release,Kendo UI for Angular 2 的第一批控件已经发布了,当前是 Beta 版本,免 ...
- BZOJ 1588 营业额统计
Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...