首先介绍IndexSearch几个常用方法,其他search方法的具体含义请查找lucene API
- void search(Collector results)//低版本Lucene的search方法
- TopDocs search(Query query,int n)//返回前n条结果
- TopDocs searchAfter(ScoreDoc after,Query query,int n)//从after以下下查找n条结果
一、利用TopScoreDocCollector进行分页
- Query query = MultiFieldQueryParser.parse(Version.LUCENE_35,searchString, fields, clauses, ikAnalyzer);//创建一个查询
- TopScoreDocCollectortopCollector=TopScoreDocCollector.create(indexSearch.maxDoc(), false);//返回所有条数的一个集合
- indexSearch.search(query, topCollector);
- System.out.println("一共有多少条记录命中:"+topCollector.getTotalHits());
- int start = (page - 1) * pageMaxCount;//start:开始条数 pageMaxCount:显示多少条
- ScoreDoc[]docs= topCollector.topDocs(start, pageMaxCount).scoreDocs;
- for (int i = 0; i < docs.length; i++) {
- Document doc = indexSearch.doc(docs[i].doc);
- //......获取结果操作
- }
一、利用 search(Query query,int n)分页
- 主要思路是先得到前n条结果,然后舍弃前面页码的结果,得到页面的结果
- 如每页的显示数量:pageCount=10,要查询第10页的结果,那么先查出10*10=100条的结果,丢掉前90条结果就是最终的结果!
- //索引排序条件
- SortField[] sortfield = new SortField[] { SortField.FIELD_SCORE,
- new SortField(null,SortField.DOC, true) };
- Sort sort = new Sort(sortfield);
- TopDocs topDocs = searcher.search(query, null, 10, sort);
- System.out.println("检索到总数:" + topDocs.totalHits);
- ScoreDoc[] scoreDocs = topDocs.scoreDocs;
二、利用searchAfter(ScoreDoc after,Query query,int n)分页
- Query query=queryParser.parse(str);
- TopDocs result = indexSearch.search(query,10);
- intindex=(page.getCurrentPage()-1)*page.getPageSize();
- ScoreDoc scoreDoc=null;
- //若是当前页是第一页面scoreDoc=null。
- if(index>0){
- //因为索引是从0开端所以要index-1
- scoreDoc=result.scoreDocs[index-1];
- }
- scoreDoc=result.scoreDocs[index-1];
- TopDocs hits= indexSearch.searchAfter(scoreDoc, query, page.getPageSize());
三、一个完整的分页实例
package com.tan.research;
import java.io.IOException;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
public class TestSearchAfter {
static Directory directory = new RAMDirectory();
public static void main(String[] args) throws Exception {
CreateIndex();
search(5,2 );
}
public static void CreateIndex() throws CorruptIndexException,LockObtainFailedException, IOException {
String[] ids = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10","11" };
String[] bookName = { "java start", "java begin", "java in action","java web", "java ssh", "java 6", "java 7", "java 8", "java 9", "java 10", "java 11" };
String[] page = { "300", "400", "256", "302", "279", "214", "400","256", "302", "279", "214" };
String[] price = { "89", "99", "70", "60", "120", "87", "98", "77","65", "160", "55" };
IndexWriter indexWriter = new IndexWriter(directory,new IndexWriterConfig(Version.LUCENE_34, new StandardAnalyzer(Version.LUCENE_34)));
for (int i = 0; i < ids.length; i++) {
Document doc = new Document();
doc.add(new Field("id", ids[i], Field.Store.YES,Field.Index.NOT_ANALYZED));
doc.add(new Field("bookName", bookName[i], Field.Store.YES,Field.Index.ANALYZED));
doc.add(new Field("page", page[i], Field.Store.YES,Field.Index.NOT_ANALYZED));
doc.add(new Field("price", price[i], Field.Store.YES,Field.Index.NOT_ANALYZED));
indexWriter.addDocument(doc);
}
System.out.println("total:" + indexWriter.numDocs());
indexWriter.close();
}
/**
*
* @param currentPage 当前页
* @param pageSize 页大小
* @throws Exception
*/
public static void search(int currentPage, int pageSize) throws Exception {
Term term = new Term("bookName", "java");
Query query = new TermQuery(term);
IndexSearcher indexSearcher = new IndexSearcher(directory);
Sort sort = new Sort();
SortField sortField = new SortField("price", SortField.INT, false);
sort.setSort(sortField);
TopDocs topDocs= indexSearcher.search(query, indexSearcher.maxDoc(), sort);//取出所有的
int start=(currentPage-1)*pageSize;
int end=start+pageSize-1;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
System.out.println("分页前:");
ScoreDoc [] scoreDoc = topDocs.scoreDocs;
SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter(
"<font color='red'>", "</font>");
// 查询一个Lucen的查询,并把查询出来的指定位置加上设定的高亮格式
Highlighter highlighter = new Highlighter(simpleHTMLFormatter,
new QueryScorer(query));
// 设置含有关键字文本块的大小
highlighter.setTextFragmenter(new SimpleFragmenter(60));
for(int i=0;i<scoreDoc.length;i++){
Document d = indexSearcher.doc(scoreDoc[i].doc);
System.out.println(d.get("bookName")+"\t"+d.get("page")+"\t"+d.get("price"));
}
System.out.println("第"+currentPage+"页分页后:");
for(int i=start;i<=end;i++){
Document d = indexSearcher.doc(scoreDocs[i].doc);
String bookname= highlighter.getBestFragment(new IKAnalyzer(), "topic", d.get("bookName"));
System.out.println("bookname:"+bookname);
System.out.println("bookName" + d.get("bookName") + "\t"
+ d.get("page") + "\t" + "price:" + d.get("price"));
}
}
}
运行结果:
匹配的total10
分页前:
java 11:::214:::55
java web:::302:::60
java 9:::302:::65
java in action:::256:::70
java 6:::214:::87
java start:::300:::89
java 7:::400:::98
java begin:::400:::99
java ssh:::279:::120
java 10:::279:::160
第2页分页后:
bookname:<font color='red'>java</font> start-------price:89
bookname:<font color='red'>java</font> 7-------price:98
bookname:<font color='red'>java</font> begin-------price:99
bookname:<font color='red'>java</font> ssh-------price:120
bookname:<font color='red'>java</font> 10-------price:160