2017-02-16 26 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