Index: lucene/demo/src/java/org/apache/lucene/demo/core/SortExample.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- lucene/demo/src/java/org/apache/lucene/demo/core/SortExample.java	(revision )
+++ lucene/demo/src/java/org/apache/lucene/demo/core/SortExample.java	(revision )
@@ -0,0 +1,202 @@
+package org.apache.lucene.demo.core;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.DoubleDocValuesField;
+import org.apache.lucene.document.DoubleField;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.document.LongField;
+import org.apache.lucene.document.TextField;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexDocument;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.index.StoredDocument;
+import org.apache.lucene.search.FieldCache;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.Version;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SortExample {
+
+  private static final Version DEMO_VERSION = Version.LUCENE_50;
+  private static final int MAX_DOCS = 5;
+
+  // Field names.
+  public static final String TITLE_FIELD = "title";
+  public static final String INT_FIELD = "field of type int";
+  public static final String DOUBLE_FIELD = "field of type double";
+  public static final String LONG_FIELD = "field of type long";
+  public static final String NUMERIC_DOC_VALUES_FIELD = "numeric doc values field";
+
+  // Fields added to documents. Created only once, reused.
+  private final TextField titleField = new TextField(TITLE_FIELD, "", Field.Store.YES);
+  private final IntField intField = new IntField(INT_FIELD, 0, Field.Store.YES);
+  private final DoubleField doubleField = new DoubleField(DOUBLE_FIELD, 0.0, Field.Store.YES);
+  private final LongField longField = new LongField(LONG_FIELD, 0l, Field.Store.YES);
+  private final DoubleDocValuesField numericDocValuesField = new DoubleDocValuesField(NUMERIC_DOC_VALUES_FIELD, 0.0);
+
+  public static final HashMap<String, SortField.Type> searchFieldsToTypes = new HashMap<>();
+
+  static {
+    searchFieldsToTypes.put(INT_FIELD, SortField.Type.INT);
+    searchFieldsToTypes.put(DOUBLE_FIELD, SortField.Type.DOUBLE);
+    searchFieldsToTypes.put(LONG_FIELD, SortField.Type.LONG);
+  }
+
+  public static void main(String[] args) throws IOException {
+    SortExample sortExample = new SortExample();
+
+    for (Map.Entry<String, SortField.Type> entry : searchFieldsToTypes.entrySet()) {
+      Directory indexDir = new RAMDirectory();
+      String sortFieldName = entry.getKey();
+      SortField.Type sortFieldType = entry.getValue();
+      sortExample.runSearchWithSort(indexDir, sortFieldName, sortFieldType);
+    }
+
+    Directory indexDir = new RAMDirectory();
+    sortExample.runSearchWithSortByDocValues(indexDir);
+  }
+
+  public TopDocs runSearchWithSort(Directory indexDir, String sortFieldName, SortField.Type sortFieldType)
+      throws IOException {
+    index(indexDir);
+    IndexSearcher searcher = createSearcher(indexDir);
+    // Query the index and sort the results by numeric fields.
+    TopDocs topDocs = queryWithSort(searcher, sortFieldName, sortFieldType);
+    displayResults(sortFieldName, searcher, topDocs, sortFieldType.name());
+    return topDocs;
+  }
+
+  public TopDocs runSearchWithSortByDocValues(Directory indexDir) throws IOException {
+    index(indexDir);
+    IndexSearcher searcher = createSearcher(indexDir);
+    // Query the index and sort the results  by docValues.
+    TopDocs topDocs = queryWithSortByDocValues(searcher, NUMERIC_DOC_VALUES_FIELD, SortField.Type.DOUBLE);
+    displayDocValuesResults(indexDir, NUMERIC_DOC_VALUES_FIELD, searcher, topDocs, SortField.Type.DOUBLE.name());
+    return topDocs;
+  }
+
+  private IndexSearcher createSearcher(Directory indexDir) throws IOException {
+    IndexReader indexReader = DirectoryReader.open(indexDir);
+    return new IndexSearcher(indexReader);
+  }
+
+  private TopDocs queryWithSort(IndexSearcher searcher, String sortFieldName, SortField.Type sortFieldType)
+      throws IOException {
+    SortField sortField = new SortField(sortFieldName, sortFieldType);
+    Sort sort = new Sort(sortField);
+    return searcher.search(new MatchAllDocsQuery(), MAX_DOCS, sort);
+  }
+
+  private TopDocs queryWithSortByDocValues(IndexSearcher searcher, String sortFieldName, SortField.Type sortFieldType)
+      throws IOException {
+    SortField sortField = new SortField(sortFieldName, sortFieldType);
+    Sort sort = new Sort(sortField);
+    return searcher.search(new MatchAllDocsQuery(), MAX_DOCS, sort);
+  }
+
+  private static void displayDocValuesResults(Directory indexDir, String sortFieldName, IndexSearcher searcher, TopDocs topDocs,
+                                              String fieldType) throws IOException {
+    ScoreDoc[] scoreDocs = topDocs.scoreDocs;
+    displayHeader(sortFieldName, fieldType, scoreDocs.length);
+    // Get double doc values.
+    DirectoryReader indexReader = DirectoryReader.open(indexDir);
+    AtomicReader atomicReader = SlowCompositeReaderWrapper.wrap(indexReader);
+    FieldCache.Doubles doubles = FieldCache.DEFAULT.getDoubles(atomicReader, sortFieldName, true);
+    // Display value for each obtained result.
+    for (int i = 0; i < scoreDocs.length; i++) {
+      int docId = scoreDocs[i].doc;
+      double value = doubles.get(docId);
+      System.out.println(searcher.doc(docId).get(TITLE_FIELD) + ": " + sortFieldName + "=" + value);
+    }
+  }
+
+  private static void displayResults(String sortFieldName, IndexSearcher searcher, TopDocs topDocs,
+                                     String fieldType) throws IOException {
+    ScoreDoc[] scoreDocs = topDocs.scoreDocs;
+    displayHeader(sortFieldName, fieldType, scoreDocs.length);
+    // Display title and the value of a sort field for each document in the results.
+    for (int i = 0; i < scoreDocs.length; i++) {
+      int docId = scoreDocs[i].doc;
+      StoredDocument storedDocument = searcher.doc(docId);
+      System.out.println(storedDocument.get(TITLE_FIELD) + ": " + storedDocument.getField(sortFieldName).name() +
+          "=" + storedDocument.getField(sortFieldName).stringValue());
+    }
+  }
+
+  private static void displayHeader(String sortFieldName, String fieldType, int numberOfHits) {
+    System.out.println("----------------------------------------------------");
+    System.out.println("Sorting by " + fieldType + " field.");
+    System.out.println("----------------------------------------------------");
+    System.out.println("Sorting results by " + sortFieldName);
+    System.out.println("Number of hits: " + numberOfHits);
+  }
+
+  private void index(Directory indexDir) throws IOException {
+    IndexWriter indexWriter = new IndexWriter(indexDir, new IndexWriterConfig(DEMO_VERSION,
+        new StandardAnalyzer(DEMO_VERSION)));
+    indexDocuments(indexWriter);
+    indexWriter.commit();
+    indexWriter.close();
+  }
+
+  private void indexDocuments(IndexWriter indexWriter) throws IOException {
+    // parameters for fields: title, intField, longField, doubleField, date, numericDocValueField
+    indexWriter.addDocument(documentOf("document 0", 10, 10967l, 1.3, 0.6));
+    indexWriter.addDocument(documentOf("document 1", 5, 0l, 0.3, 1.4));
+    indexWriter.addDocument(documentOf("document 2", 3, -123l, -2.6, 0.9));
+    indexWriter.addDocument(documentOf("document 3", 7, 9876l, 1.0, 2.7));
+    indexWriter.addDocument(documentOf("document 4", 1, 342l, 6.8, 8.9));
+  }
+
+  private IndexDocument documentOf(String title, int intNumber, long longNumber, double doubleNumber,
+                                   double doubleDocValue) {
+    titleField.setStringValue(title);
+    intField.setIntValue(intNumber);
+    longField.setLongValue(longNumber);
+    doubleField.setDoubleValue(doubleNumber);
+    numericDocValuesField.setDoubleValue(doubleDocValue);
+
+    Document document = new Document();
+
+    document.add(titleField);
+    document.add(intField);
+    document.add(longField);
+    document.add(doubleField);
+    document.add(numericDocValuesField);
+
+    return document;
+  }
+}
Index: lucene/demo/src/test/org/apache/lucene/demo/core/TestSortExample.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- lucene/demo/src/test/org/apache/lucene/demo/core/TestSortExample.java	(revision )
+++ lucene/demo/src/test/org/apache/lucene/demo/core/TestSortExample.java	(revision )
@@ -0,0 +1,82 @@
+package org.apache.lucene.demo.core;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class TestSortExample extends LuceneTestCase {
+
+  @Test
+  public void testSortByIntField() throws IOException {
+    int[] order = new int[]{4, 2, 1, 3, 0};
+    String sortFieldName = SortExample.INT_FIELD;
+    SortField.Type sortFieldType = SortExample.searchFieldsToTypes.get(sortFieldName);
+
+    TopDocs topDocs = new SortExample().runSearchWithSort(new RAMDirectory(), sortFieldName, sortFieldType);
+
+    assertEquals(5, topDocs.totalHits);
+    assertOrder(order, topDocs.scoreDocs);
+  }
+
+  private void assertOrder(int[] order, ScoreDoc[] result) {
+    for (int i = 0; i < result.length; i++) {
+      assertEquals(order[i], result[i].doc);
+    }
+  }
+
+  @Test
+  public void testSortByDoubleField() throws IOException {
+    int[] order = new int[]{2, 1, 3, 0, 4};
+    String sortFieldName = SortExample.DOUBLE_FIELD;
+    SortField.Type sortFieldType = SortExample.searchFieldsToTypes.get(sortFieldName);
+
+    TopDocs topDocs = new SortExample().runSearchWithSort(new RAMDirectory(), sortFieldName, sortFieldType);
+
+    assertEquals(5, topDocs.totalHits);
+    assertOrder(order, topDocs.scoreDocs);
+  }
+
+  @Test
+  public void testSortByLongField() throws IOException {
+    int[] order = new int[]{2, 1, 4, 3, 0};
+    String sortFieldName = SortExample.LONG_FIELD;
+    SortField.Type sortFieldType = SortExample.searchFieldsToTypes.get(sortFieldName);
+
+    TopDocs topDocs = new SortExample().runSearchWithSort(new RAMDirectory(), sortFieldName, sortFieldType);
+
+    assertEquals(5, topDocs.totalHits);
+    assertOrder(order, topDocs.scoreDocs);
+  }
+
+  @Test
+  public void testSortByDocValuesField() throws IOException {
+    int[] order = new int[]{0, 2, 1, 3, 4};
+
+    TopDocs topDocs = new SortExample().runSearchWithSortByDocValues(new RAMDirectory());
+
+    assertEquals(5, topDocs.totalHits);
+    assertOrder(order, topDocs.scoreDocs);
+  }
+}
