Lucene的简单查询(二)

本文介绍了Lucene搜索引擎中的查询技巧,包括基本查询方法、排序、过滤及多域查询等核心功能。通过示例展示了如何使用不同的查询方式来提高搜索效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、查询

    1.查询的基本方法

           search.search(query, results)
	   search.search(query, n)
	   search.search(query, filter, results)
	   search.search(query, filter, n)
	   search.search(query, n, sort)
	   search.search(query, filter, n, sort)
	   search.search(query, filter, n, sort, doDocScores, doMaxScore)

    2.平时常用的基本方法 排序

search(query,n)//这样自动排一个序,根据文档的综合得分 倒序排列

    

search.search(query, n, Sort.INDEXORDER); //根据doc的ID来排序的

 

search.search(query, n, Sort.RELEVANCE);跟默认的分排序时一样的

   

search.search(query,n, new Sort(new SortField("time", SortField.Type.LONG)));//但是添加了一个域用添加索引的时间,这样排序是根据整个索引匹配的时间向下递增的

 

search.search(query, n, new Sort(new SortField("time", SortField.Type.LONG,true))); //倒排

   过滤

         Term t=new Term("type","俄国");
	  Query query_2=new TermQuery(t);
	  Filter categoryFilter=new QueryWrapperFilter(query_2);
	   TopDocs hits =search.search(query, categoryFilter, 10);
//把类别是俄国的从结果中筛选出来。结果还是按照得分倒排的

 

当然生成Sort的时候还可以添加多个,SortField实例化的时候是一个变参。

 

SortField.Type属性有多个有数据类型的,还有SCORE,DOC对准文档的。

三 、MultiPhraseQuery

基本的用法

   MultiPhraseQuery query=new MultiPhraseQuery();
	   query.add(new Term[]{new Term("countent","兴奋"),new Term("countent","高兴")});
           query.add();//接着添加一个之不过应该是先匹配上面的 一个方面的多种情况
	   TopDocs hits=search.search(query, 10);
//是可以在同一个域中进行多项匹配索引。相当于or。不同域会报错的

 转换//

 PhraseQuery p=new PhraseQuery();
	   p.setSlop(1);
	   p.add(new Term("countent","兴奋"));
	   p.add(new Term("countent","高兴"));
	   
	   PhraseQuery pp=new PhraseQuery();
	   pp.add(new Term("countent","快乐"));
	   pp.add(new Term("countent","高兴"));
	   
	   BooleanQuery query=new BooleanQuery();
	   query.add(p,BooleanClause.Occur.SHOULD);
	   
	   query.add(pp,BooleanClause.Occur.SHOULD);
	   
//p.setSlop(int);匹配因子可以精确查询,默认是0则是相邻的词组,不是则在这个范围内。

 四、多域查询

   1.直接用MultiFieldQueryParser进行跟据它的一些语法;

 Query query=new MultiFieldQueryParser(Version.LUCENE_42,new String[]{"countent","type"},new SmartChineseAnalyzer(Version.LUCENE_42)).parse("俄国 前少年");
	   TopDocs hits=search.search(query, 10);

 

 中间的是:域和分词

  Query query=MultiFieldQueryParser.parse(Version.LUCENE_42, "俄国青少年", new String[]{"countent","type"},
			   new BooleanClause.Occur[]{BooleanClause.Occur.MUST,BooleanClause.Occur.MUST},new SmartChineseAnalyzer(Version.LUCENE_42) );
	   
	   TopDocs hits=search.search(query, 10);

 

 
 中间的是:域和分词

### 关于Lucene分页查询的实现 Lucene提供了强大的搜索功能,其中包括分页查询的支持。通过`IndexSearcher`类及其相关方法,可以轻松实现分页查询的功能[^3]。 以下是基于Lucene的分页查询实现方式: #### 1. 使用TopDocs进行分页 Lucene中的`IndexSearcher.search(Query query, int num)`方法返回的是前`num`个匹配的结果。为了实现分页查询,可以通过调整参数来控制每一页显示的数量以及跳过前面已经展示过的文档数量。 具体来说,`search(Query query, Filter filter, int n)`允许指定最大返回结果数`n`,而`searchAfter(ScoreDoc after, Query query, int n)`则用于从某个特定位置继续获取下一批数据。 下面是一个简单的分页查询代码示例: ```java import org.apache.lucene.document.Document; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; public class LucenePaginationExample { public static void searchWithPaging(IndexSearcher searcher, Query query, int pageSize, int pageNumber) throws Exception { int start = (pageNumber - 1) * pageSize; // 计算起始位置 TopDocs topDocs = searcher.search(query, start + pageSize); // 获取总结果集 ScoreDoc[] scoreDocs = topDocs.scoreDocs; System.out.println("Total Hits: " + topDocs.totalHits); if (scoreDocs.length > start) { // 如果有更多记录,则处理当前页面的数据 for (int i = start; i < Math.min(scoreDocs.length, start + pageSize); i++) { Document doc = searcher.doc(scoreDocs[i].doc); System.out.println(doc.get("id") + ": " + doc.get("content")); } } else { System.out.println("No more results."); } } public static void main(String[] args) throws Exception { DirectoryReader reader = DirectoryReader.open(FSDirectory.open(Paths.get("/path/to/index"))); IndexSearcher searcher = new IndexSearcher(reader); QueryParser parser = new QueryParser("content", new StandardAnalyzer()); Query query = parser.parse("example"); int pageSize = 10; // 每页大小 int pageNumber = 1; // 当前页码 searchWithPaging(searcher, query, pageSize, pageNumber); reader.close(); } } ``` 此代码展示了如何利用`start`变量计算偏移量并结合`pageSize`完成分页逻辑[^3]。 #### 2. 高效的大规模分页方案 对于大规模数据场景下的高效分页操作,推荐使用`searchAfter()`方法替代传统的`search()`方法。这种方法能够显著减少内存消耗和性能开销,因为它不需要一次性加载所有可能的结果到内存中。 示例如下: ```java ScoreDoc lastHit = null; if (pageNumber > 1 && previousLastHit != null) { lastHit = previousLastHit; } TopDocs topDocs = searcher.searchAfter(lastHit, query, pageSize); previousLastHit = topDocs.scoreDocs[topDocs.scoreDocs.length - 1]; // 处理topDocs... ``` 这里的关键在于保存每次请求最后一条命中项的信息(`lastHit`)以便下次调用时作为起点传递给`searchAfter()`函数[^3]。 --- ### 总结 以上两种方法都可以用来实现Lucene中的分页查询功能。第一种适用于中小型数据集合上的简单应用场合;第种更适合大数据环境下的优化需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值