一、排序介绍
Lucene对文档搜索完成后,显示的结果是有一个顺序的,如果没有设置排序规则,那么这个顺序就是按照文档的评分降序排列,至于评分的计算,是一个比较复杂的公式,这里不先研究了。可是有时候,我们需要根据需求,改变默认的排序规则,这时候就要用到自定义排序啦,下面来看一下自定义排序是怎么使用的吧。
二、代码演示
package com.wsy;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CustomSortTest {
private static Directory directory;
private static IndexReader indexReader;
static {
try {
directory = FSDirectory.open(new File("E:\\Lucene\\IndexLibrary"));
indexReader = IndexReader.open(directory);
} catch (IOException e) {
e.printStackTrace();
}
}
public void index(boolean update) {
IndexWriter indexWriter = null;
try {
indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
if (update) {
indexWriter.deleteAll();
}
File[] files = new File("E:\\Lucene\\SearchSource").listFiles();
for (File file : files) {
Document document = new Document();
document.add(new Field("content", new FileReader(file)));
document.add(new Field("fileName", file.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED));
document.add(new Field("path", file.getAbsolutePath(), Field.Store.YES, Field.Index.NOT_ANALYZED));
document.add(new NumericField("date", Field.Store.YES, true).setLongValue(file.lastModified()));
document.add(new NumericField("size", Field.Store.YES, true).setIntValue((int) (file.length())));
indexWriter.addDocument(document);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (indexWriter != null) {
try {
indexWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public IndexSearcher getIndexSearcher() {
try {
if (indexReader == null) {
indexReader = IndexReader.open(directory);
} else {
IndexReader temp = IndexReader.openIfChanged(indexReader);
if (temp != null) {
indexReader.close();
indexReader = temp;
}
}
return new IndexSearcher(indexReader);
} catch (CorruptIndexException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void searcher(String queryString, Sort sort) {
try {
IndexSearcher indexSearcher = getIndexSearcher();
QueryParser queryParser = new QueryParser(Version.LUCENE_35, "content", new StandardAnalyzer(Version.LUCENE_35));
Query query = queryParser.parse(queryString);
TopDocs topDocs;
if (sort != null) {
topDocs = indexSearcher.search(query, 100, sort);
} else {
topDocs = indexSearcher.search(query, 100);
}
ScoreDoc[] scoreDocs = topDocs.scoreDocs;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (ScoreDoc scoreDoc : scoreDocs) {
Document document = indexSearcher.doc(scoreDoc.doc);
// 依次输出文档id,文档得分,文档名字,文档路径,文档大小,文档修改时间
System.out.println(scoreDoc.doc + "-->" + scoreDoc.score + "-->" + document.get("fileName") + "-->" + document.get("path") + "-->" + document.get("size") + "-->" + simpleDateFormat.format(new Date(Long.valueOf(document.get("date")))));
}
indexSearcher.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
CustomSortTest customSortTest = new CustomSortTest();
customSortTest.index(true);
// 默认排序(按照评分从高到底降序排列)
System.out.println("默认排序(按照评分从高到底降序排列)");
customSortTest.searcher("java", null);
// Sort.INDEXORDER是通过doc的id进行升序排序
System.out.println("Sort.INDEXORDER是通过doc的id进行升序排序");
customSortTest.searcher("java", Sort.INDEXORDER);
// Sort.RELEVANCE是按照关联性来排序
System.out.println("Sort.RELEVANCE是按照关联性来排序");
customSortTest.searcher("java", Sort.RELEVANCE);
// 自定义排序,默认是升序,如果需要降序,根据SortField(String field, int type, boolean reverse)构造方法,多传一个true即可
System.out.println("自定义排序,这里是按照文件大小升序排序");
customSortTest.searcher("java", new Sort(new SortField("size", SortField.INT)));
System.out.println("自定义排序,这里是按照文件日期升序排序");
customSortTest.searcher("java", new Sort(new SortField("date", SortField.LONG)));
System.out.println("自定义排序,这里是按照文件名称升序排序");
customSortTest.searcher("java", new Sort(new SortField("fileName", SortField.STRING)));
// 多字段排序
System.out.println("自定义多字段排序,这里是先按照文件日期升序排序,再按照大小降序");
customSortTest.searcher("java", new Sort(new SortField("date", SortField.LONG), new SortField("size", SortField.INT, true)));
}
}