2017-02-16 27 views
2

我想根據數字字段對我的搜索結果進行排序。 在下面的示例代碼中,我想根據「年齡」字段進行排序。 我使用的答案從開始:如何排序Lucene中的數字字段6

[How to sort IntPont or LongPoint field in Lucene 6

但它確實排序依據得分。年齡還沒有上升。

而且

[Sorting search result in Lucene based on a numeric field

我在搜索功能改變SortField.Type.SCORE到SortField.Type.LONG。 但我得到:

意外docvalues類型NONE現場 '年齡'(預期= NUM​​ERIC)

這裏我的代碼:

public class TestLongPointSort { 


    public static void main(String[] args) throws Exception { 

     String indexPath = "/tmp/testSort"; 
     Analyzer standardAnalyzer = new StandardAnalyzer(); 
     Directory indexDir = FSDirectory.open(Paths.get(indexPath)); 
     IndexWriterConfig iwc = new IndexWriterConfig(standardAnalyzer); 

     iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND); 

     IndexWriter masterIndex = new IndexWriter(indexDir, iwc); 

     Document doc = new Document(); 

     String name = "bob"; 
     doc.add(new TextField("name", name, Field.Store.YES)); 
     doc.add(new SortedDocValuesField("name", new BytesRef(name))); 
     doc.add(new SortedNumericDocValuesField("age", 20L)); 
     doc.add(new StoredField("age", 20L)); 
     long ts = System.currentTimeMillis(); 
     doc.add(new SortedNumericDocValuesField("ts", ts)); 
     doc.add(new StoredField("ts", ts)); 
     masterIndex.addDocument(doc); 
     Thread.sleep(1); 

     name = "max"; 
     doc = new Document(); 
     doc.add(new TextField("name", name, Field.Store.YES)); 
     doc.add(new SortedDocValuesField("name", new BytesRef(name))); 
     doc.add(new SortedNumericDocValuesField("age", 19L)); 
     doc.add(new StoredField("age", 19L)); 
     ts = System.currentTimeMillis(); 
     doc.add(new SortedNumericDocValuesField("ts", ts)); 
     doc.add(new StoredField("ts", ts)); 
     masterIndex.addDocument(doc); 
     Thread.sleep(1); 

     name = "jim"; 
     doc = new Document(); 
     doc.add(new TextField("name", name, Field.Store.YES)); 
     doc.add(new SortedDocValuesField("name", new BytesRef(name))); 
     doc.add(new SortedNumericDocValuesField("age", 21L)); 
     doc.add(new StoredField("age", 21L)); 
     ts = System.currentTimeMillis(); 
     doc.add(new SortedNumericDocValuesField("ts", ts)); 
     doc.add(new StoredField("ts", ts)); 
     masterIndex.addDocument(doc); 

     masterIndex.commit(); 
     masterIndex.close(); 

     IndexReader reader = DirectoryReader.open(FSDirectory.open(Paths.get(indexPath))); 
     IndexSearcher searcher = new IndexSearcher(reader); 

     Analyzer analyzer = new KeywordAnalyzer(); 
     QueryParser queryParser = new QueryParser("message", analyzer); 

     Sort sort; 
     TopDocs docs; 
     sort = new Sort(new SortField("name", SortField.Type.STRING)); 
     docs = searcher.search(new MatchAllDocsQuery(), 100, sort); 
     System.out.println("Sorted by name"); 
     for (ScoreDoc scoreDoc : docs.scoreDocs) { 
      Document doc2 = searcher.doc(scoreDoc.doc); 
      System.out.println("Name:" + doc2.get("name") + " ; age:" + doc2.get("age") + " ; ts:" + doc2.get("ts")); 
     } 

     //docs = searcher.search(new MatchAllDocsQuery(), 100, new Sort(new SortField("age", SortField.Type.SCORE, true))); 
     docs = searcher.search(new MatchAllDocsQuery(), 100, new Sort(new SortField("age", SortField.Type.LONG, true))); 
     System.out.println("Sorted by age"); 
     for (ScoreDoc scoreDoc : docs.scoreDocs) { 

      Document doc2 = searcher.doc(scoreDoc.doc); 
      System.out.println("Name:" + doc2.get("name") + " ; age:" + doc2.get("age") + " ; ts:" + doc2.get("ts")); 
     } 

     reader.close(); 

    } 
} 

我們可以看到,分揀STRING被不錯,但我沒有弄清楚如何讓我的數字(長)分類。

什麼是排序數字字段的正確方法?

感謝

回答

2

要使用SortedNumericDocValuesField搜索結果進行排序,你需要使用一個SortedNumericSortField

Sort sort = new Sort(new SortedNumericSortField("age", SortField.Type.LONG, true)); 
TopDocs docs = searcher.search(new MatchAllDocsQuery(), 100, sort); 
+0

其實,我也嘗試了這一個。仍然有錯誤。只是不同的:意外的文檔類型NONE爲字段'年齡'(期望[SORTED_NUMERIC,NUMERIC]之一) – moonbeam

+0

@moonbeam - 合理地確信你錯了,是我用這個修改運行*你的代碼*,它工作得很好。 – femtoRgon

+0

我確實剪下粘貼你的代碼。你使用的是什麼版本的Lucene?我正在使用6.4.1 – moonbeam

0

我會建議你使用ArrayList來存儲來自文件的數據,而不是將其保存到另一個文件中,然後使用ArrayList的排序方法。

請訪問這些鏈接供您參考。

SO - how to sort arraylist

JAVA ArrayList sort method sample

+0

是的,這是可以做到這樣的,但它意味着複製整個搜索結果存入內存並從Lucene外部對其進行排序 這個想法是使用Lucene記錄的分類容量。 這個問題是要弄清楚如何使用這個Lucene功能對數字字段進行排序,因爲我能夠對字符串字段進行排序 – moonbeam