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对象创 ...
随机推荐
- 线程取消 (pthread_cancel)
线程取消(pthread_cancel) 基本概念pthread_cancel调用并不等待线程终止,它只提出请求.线程在取消请求(pthread_cancel)发出后会继续运行,直到到达某个取消点(C ...
- CentOS Device eth0 does not seem to be present 解决方案
1. vi /etc/udev/rules.d/70-persistent-net.rules 记录eth1 的网卡地址 2.vi /etc/sysconfig/network-scrpits/ifc ...
- magento后台 Fatal error: Call to a member function getId() on a non-object in错误
后台分类管理出现错误 Fatal error: Call to a member function getId() on a non-object in 在数据库中运行以下sql语句 INSERT I ...
- jquery 获取元素的 实际宽度和高度
jquery outerHeight方法 outerWidth方法 转: http://www.cnblogs.com/zhja/archive/2012/11/07/2758665.html jqu ...
- openerp import l field size limit
modify the file addons/base_import/models.py add the following line at the very begining of the _con ...
- android开发学习笔记:圆角的Button
转自:http://www.cnblogs.com/gzggyy/archive/2013/05/17/3083218.html 在res目录下的drawable-mdpi建立xml文件shape.x ...
- Tag Helpers 介绍
Tag Helpers 介绍 原文:Introduction to Tag Helpers作者:Rick Anderson翻译:刘浩杨校对:高嵩(Jack) 什么是 Tag Helpers? Tag ...
- 设计模式——如何避免在OO设计中违反依赖倒置原则
1 变量不可以包含具体类的引用.一旦new,就对具体类产生依赖,用工厂模式来避开. 2 类不要派生至具体类.用派生抽象类避开. 3 不要覆盖基类已经实现的方法.基类中已实现的方法应该由所有子类共享.
- windows 下安装nodejs及其配置环境
第一步:下载安装文件下载nodejs,官网:http://nodejs.org/download/,我这里下载的是node-v0.10.28-x86.msi,如下图: 第二步:安装nodejs下载完成 ...
- myeclipse spket spket-1.6.23.jar 破解安装教程
一年前安装文档就写过了,今天写破解文档,本来开发js/ext是想用aptana的,但是安装包100多M,我还是用spket吧(才11M),这个需要破解一下license,否则用不了. 一 安装教程如下 ...