在Lucene4.6中,想要實現搜索結果按照時間倒序的效果:若是兩個文檔得分相同,那麼就按照發布時間倒序排列;不然就按照分數排列。這種效果在 Lucene4.6中實現起來極其簡單,直接利用search接口的Sort參數便可達成,徹底不須要像某些人說的重寫Similarity那麼麻煩。三 兩行代碼的事情,體現了Make it simple, stupid的精髓。java
package com.hankcs.test; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.*; import org.apache.lucene.index.*; import org.apache.lucene.queries.CustomScoreQuery; import org.apache.lucene.queries.function.FunctionQuery; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.*; 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; import java.io.IOException; /** * @author hankcs */ public class TestSortByTime{ public static void main(String[] args) { // Lucene Document的主要域名 String fieldName = "text"; // 實例化IKAnalyzer分詞器 Analyzer analyzer = new IKAnalyzer(); Directory directory = null; IndexWriter iwriter; IndexReader ireader = null; IndexSearcher isearcher; try { //索引過程********************************** //創建內存索引對象 directory = new RAMDirectory(); //配置IndexWriterConfig IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_46, analyzer); iwConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND); iwriter = new IndexWriter(directory, iwConfig); //寫入索引 for (int i = 0; i < 3; ++i) { int year = 2004 + i; Document doc = new Document(); doc.add(new TextField(fieldName, year + "全民突擊攻略", Field.Store.YES)); doc.add(new IntField("date", year * 10000 + 1111, Field.Store.YES)); iwriter.addDocument(doc);} // 加入一個干擾文檔 Document doc = new Document(); doc.add(new TextField(fieldName, "每天酷跑攻略", Field.Store.YES)); doc.add(new IntField("date", 20141111, Field.Store.YES)); iwriter.addDocument(doc); iwriter.close(); //搜索過程********************************** //實例化搜索器 ireader = DirectoryReader.open(directory); isearcher = new IndexSearcher(ireader); String keyword = "全民突擊攻略"; //使用QueryParser查詢分析器構造Query對象 QueryParser qp = new QueryParser(Version.LUCENE_46, fieldName, analyzer); Query query = qp.parse(keyword); System.out.println("Query = " + query); //搜索類似度最高的5條記錄 Sort sort = new Sort(new SortField("text", SortField.Type.SCORE), new SortField("date", SortField.Type.INT, true)); To pDocs topDocs = isearcher.search(query, 5, sort); System.out.println("命中:" + topDocs.totalHits); //輸出結果 ScoreDoc[] scoreDocs = topDocs.scoreDocs; for (int i = 0; i < Math.min(5, scoreDocs.length); i++){ Document targetDoc = isearcher.doc(scoreDocs[i].doc); System.out.print(targetDoc.getField(fieldName).stringValue()); System.out.print(" , " + targetDoc.getField("date").numericValue()); System.out.println(" , " + scoreDocs[i].score); } } catch (CorruptIndexException e) { e.printStackTrace(); } catch (LockObtainFailedException e) { e.printStackTrace(); } catch (IOException e){ e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } finally { if (ireader != null) { try{ ireader.close(); } catch (IOException e) { e.printStackTrace(); } } if (directory != null) { try { directory.close(); } catch (IOException e) { e.printStackTrace(); } } } }}