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对象创 ...
随机推荐
- Servlet(一)
BS架构的优势 1.数据库之负责数据库的管理 2.Web服务器负责业务逻辑的处理 3.浏览器提供操作界面 4.不需要单独安装客户端 5.开发相对于CS简单,客户端和服务器的通信模块都是使用标准的HTT ...
- grunt 合并压缩任务
module.exports = function(grunt) { // LiveReload的默认端口号,你也可以改成你想要的端口号 var lrPort = 35729; // 使用connec ...
- phpcms v9后台美化需要修改的部分整理
PHPcms后台登陆后的页面修改 Phpcms->modules->admin->templates->main.tpl.php 1,安全提示部分 <h6>< ...
- NPOI读写Excel0307
#region NPOI 操作 Excel 2007 /// <summary> /// 将Excel文件中的数据读出到DataTable中(xlsx) /// </summary& ...
- jQuery运维开发之第十七天
JQuery 学习参考网址http://jquery.cuishifeng.cn/ python中叫模块,在DOM/BOM/Javascript中叫类库 现在的JQ版本有:1.x 2.x 3.x 建议 ...
- smali文件语法参考
Dalvik opcodes Author: Gabor Paller Vx values in the table denote a Dalvik register. Depending on th ...
- 常见的HTTPS攻击方法
0x00 背景 研究常见的https攻击方法 Beast crime breach,并针对https的特性提出一些安全部署https的建议. 针对于HTTPS的攻击,多存在于中间人攻击的环境中,主要是 ...
- couchdb and redis
http://www.jdon.com/artichect/scalable5.html http://www.dedecms.com/knowledge/data-base/nosql/2012/0 ...
- 人在江湖飘,哪能不挨刀。CENTOS之后,UBUNTU,FEDORA都要安装起来作测试啊
还好,我们有VIRTUAL BOX.
- c# 函数相关练习
1.输入一个正整数,求1!+2!+3!+...+n! 2.输入姓名,年龄,工作单位 我叫**,今年**岁了,现在在****工作 要求,在Main函数中接收这三个值 传到函数中打印 3.写一 ...