如何对Lucene 6中的数字字段进行排序

时间:2021-06-21 03:00:45

I want to sort my search result based on a numeric field. In the following example code, I want to sort based on the 'age' field. I start from using the answers from:

我想根据数字字段对搜索结果进行排序。在下面的示例代码中,我希望基于“age”字段进行排序。我从使用答案开始:

[How to sort IntPont or LongPoint field in Lucene 6

[如何在Lucene 6中对IntPont或LongPoint字段进行排序

But it does sort based SCORE. The age are still not ascending.

但它确实根据分数排序。年龄还没有上升。

And

[Sorting search result in Lucene based on a numeric field

[排序搜索结果在Lucene基于一个数字字段。

I changed SortField.Type.SCORE to SortField.Type.LONG in the search function. But I get:

我改变了SortField.Type。SortField.Type得分。在搜索功能中。但我得到:

unexpected docvalues type NONE for field 'age' (expected=NUMERIC)

字段'age'的未预期docvalues类型为NONE (expected=NUMERIC)

Here my code:

这里我的代码:

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();

    }
}

As we can see, sorting STRING is good but I didn't figure out how I can get my numbers (LONG) sorted.

正如我们所看到的,排序字符串是很好的,但是我不知道如何排序我的数字(长)。

What is the right way to sort Numeric fields?

排序数字字段的正确方法是什么?

Thanks

谢谢

2 个解决方案

#1


2  

To sort search results using a SortedNumericDocValuesField, you'll need to use a SortedNumericSortField:

要使用SortedNumericDocValuesField对搜索结果进行排序,您需要使用SortedNumericSortField:

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

#2


0  

I would suggest you use ArrayList to store data from Document rather than saving it to another document, then use sort methods of ArrayList.

我建议您使用ArrayList从文档中存储数据,而不是保存到另一个文档中,然后使用ArrayList的sort方法。

Please visit these links for your reference.

请访问这些链接以供参考。

SO - how to sort arraylist

如何排序arraylist。

JAVA ArrayList sort method sample

JAVA ArrayList排序方法示例

#1


2  

To sort search results using a SortedNumericDocValuesField, you'll need to use a SortedNumericSortField:

要使用SortedNumericDocValuesField对搜索结果进行排序,您需要使用SortedNumericSortField:

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

#2


0  

I would suggest you use ArrayList to store data from Document rather than saving it to another document, then use sort methods of ArrayList.

我建议您使用ArrayList从文档中存储数据,而不是保存到另一个文档中,然后使用ArrayList的sort方法。

Please visit these links for your reference.

请访问这些链接以供参考。

SO - how to sort arraylist

如何排序arraylist。

JAVA ArrayList sort method sample

JAVA ArrayList排序方法示例