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对象创 ...
随机推荐
- 2016年9月ccf
去长沙理工考ccf.恰好又可以见闺蜜. 前2道题很简单,第三题题目太长就跳过了[绕来绕去就像“你儿子是我儿子的爸爸一样头疼”],就做第四题.但是还有最后一个部分没写写好就到点了. 现在把它补充完整. ...
- 获取Enum的扩张方法。
public static class EnumExtention { /// <summary> /// 获取枚举的描述信息 /// </summary> /// <t ...
- python3 读写excel
一直认为python3可以很快的实现很多简单的功能,今天要读excel表格数据,想来很简单,网上一搜,用xlrd即可,然后很多人给出了不同的版本,号称xlrd3,实际上官网一看,xlrd0.9.4兼容 ...
- each函数循环数据表示列举,列举循环的时候添加dom的方法
var dotBox = $('#bannerNum');var item = '<li></li>';var itemSize = $('#bannerBack p').le ...
- 一个基于nodejs,支持http/https的中间人(MITM)代理,便于渗透测试和开发调试。
源码地址:https://github.com/wuchangming/node-mitmproxy node-mitmproxy node-mitmproxy是一个基于nodejs,支持http/h ...
- actionscript sendToURL请求url,传递http_referer分浏览器统计
IE全版本都不传递referer,但会在header中传递X_FLASH_VERSION,例如:"HTTP_X_FLASH_VERSION":"13,0,0,182&qu ...
- PHP对象类型在内存中的分配
对象类型和整型.字符串等类型一样,也是PHP中的一种数据类型.都是在程序中用于存储不同类型数据使用的,在程序运行时它的每部分内容都要先加载到内存中再被使用.那么对象类型的数据在内存中是如何分配的呢?先 ...
- PHP学习之中数组-遍历一维数组【2】
在PHP学习之中数组[1]中学会怎么创建一个数组,如果PHP学习之中数组[1]中的元素多的话,我们访问元素又是一个问题了,下面我们就使用for语句while,foreach来遍历我们的数组: < ...
- 关于DEDECMS自定义模型当中添加自定义字段后在后台添加内容后不显示解决方案
用DEDECMS的时间也不长,最近在做一个站时,就遇到了这个问题(自定义字段在后台不显示内容)中添加自定义字段后在后台编辑打开后发现我之前添加的内容不显示,如果是只是看看不单击确定的话,那么在前台数据 ...
- C#中调用WIN32的API
最近在学习C#中的GDI部分,本来尝试编写一个字幕控件(其实还是用label比较合适),但是发现控件中用GDI将整个控件粉刷貌似不行(应该是我水平不行),所以就去捣鼓了下WIN32的DLL,发现用AP ...