You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mk...@apache.org on 2019/01/28 12:27:58 UTC

[lucene-solr] branch master updated: SOLR-13156: support facet.sort for facet.field={!terms=foo, bar}field

This is an automated email from the ASF dual-hosted git repository.

mkhl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/master by this push:
     new 43f2723  SOLR-13156: support facet.sort for facet.field={!terms=foo,bar}field
43f2723 is described below

commit 43f2723213ed403a9f58d813d391ef26c961d909
Author: Mikhail Khludnev <mk...@apache.org>
AuthorDate: Sun Jan 27 15:05:40 2019 +0300

    SOLR-13156: support facet.sort for facet.field={!terms=foo,bar}field
---
 solr/CHANGES.txt                                   |  2 ++
 .../java/org/apache/solr/request/SimpleFacets.java | 39 ++++++++++++++++------
 .../test/org/apache/solr/request/TestFaceting.java | 31 +++++++++++++++++
 solr/solr-ref-guide/src/faceting.adoc              |  4 +--
 4 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 4464c4c..169081d 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -336,6 +336,8 @@ Improvements
 
 * SOLR-13029: solr.hdfs.buffer.size can be configured for HdfsBackupRepository for better performance (Tim Owen via Mikhail Khludnev)
 
+* SOLR-13156: support facet.sort for facet.field={!terms=foo,bar}field. (Konstantin Perikov via Mikhail Khludnev)
+
 Other Changes
 ----------------------
 
diff --git a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
index 4608e2d..1bea80a 100644
--- a/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
+++ b/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
@@ -18,6 +18,7 @@ package org.apache.solr.request;
 
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
+import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -35,6 +36,7 @@ import java.util.concurrent.FutureTask;
 import java.util.concurrent.RunnableFuture;
 import java.util.concurrent.Semaphore;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
@@ -861,22 +863,39 @@ public class SimpleFacets {
   }
 
   /**
-   * Computes the term-&gt;count counts for the specified term values relative to the 
+   * Computes the term-&gt;count counts for the specified term values relative to the
+   *
    * @param field the name of the field to compute term counts against
    * @param parsed contains the docset to compute term counts relative to
-   * @param terms a list of term values (in the specified field) to compute the counts for 
+   * @param terms a list of term values (in the specified field) to compute the counts for
    */
-  protected NamedList<Integer> getListedTermCounts(String field, final ParsedParams parsed, List<String> terms) throws IOException {
-    SchemaField sf = searcher.getSchema().getField(field);
-    FieldType ft = sf.getType();
-    NamedList<Integer> res = new NamedList<>();
-    for (String term : terms) {
-      int count = searcher.numDocs(ft.getFieldQuery(null, sf, term), parsed.docs);
-      res.add(term, count);
+  protected NamedList<Integer> getListedTermCounts(String field, final ParsedParams parsed, List<String> terms)
+      throws IOException {
+    final String sort = parsed.params.getFieldParam(field, FacetParams.FACET_SORT, "empty");
+    final SchemaField sf = searcher.getSchema().getField(field);
+    final FieldType ft = sf.getType();
+    final DocSet baseDocset = parsed.docs;
+    final NamedList<Integer> res = new NamedList<>();
+    Stream<String> inputStream = terms.stream();
+    if (sort.equals(FacetParams.FACET_SORT_INDEX)) { // it might always make sense
+      inputStream = inputStream.sorted();
+    }
+    Stream<SimpleImmutableEntry<String,Integer>> termCountEntries = inputStream
+        .map((term) -> new SimpleImmutableEntry<>(term, numDocs(term, sf, ft, baseDocset)));
+    if (sort.equals(FacetParams.FACET_SORT_COUNT)) {
+      termCountEntries = termCountEntries.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
     }
-    return res;    
+    termCountEntries.forEach(e -> res.add(e.getKey(), e.getValue()));
+    return res;
   }
 
+  private int numDocs(String term, final SchemaField sf, final FieldType ft, final DocSet baseDocset) {
+    try {
+      return searcher.numDocs(ft.getFieldQuery(null, sf, term), baseDocset);
+    } catch (IOException e1) {
+      throw new RuntimeException(e1);
+    }
+  }
 
   /**
    * Returns a count of the documents in the set which do not have any 
diff --git a/solr/core/src/test/org/apache/solr/request/TestFaceting.java b/solr/core/src/test/org/apache/solr/request/TestFaceting.java
index 88de349..59b3a41 100644
--- a/solr/core/src/test/org/apache/solr/request/TestFaceting.java
+++ b/solr/core/src/test/org/apache/solr/request/TestFaceting.java
@@ -900,5 +900,36 @@ public class TestFaceting extends SolrTestCaseJ4 {
       return null;
     });
   }
+
+  @Test
+  public void testListedTermCounts() throws Exception {
+    assertU(adoc("id", "1", "title_ws", "Book1"));
+    assertU(adoc("id", "2", "title_ws", "Book2"));
+    assertU(adoc("id", "3", "title_ws", "Book3"));
+    assertU(adoc("id", "4", "title_ws", "Book2"));
+    assertU(adoc("id", "5", "title_ws", "Book1"));
+    assertU(adoc("id", "6", "title_ws", "Book2"));
+    assertU(commit());
+
+    // order is the same as in facet.field, when no facet.sort specified
+    assertQ(req("q", "*:*", FacetParams.FACET, "true", FacetParams.FACET_FIELD, "{!terms=Book3,Book2,Book1}title_ws"),
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[1][@name='Book3']",
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[2][@name='Book2']",
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[3][@name='Book1']");
+
+    // order is by counts, when facet.sort by count specified
+    assertQ(req("q", "*:*", FacetParams.FACET, "true", FacetParams.FACET_FIELD, "{!terms=Book3,Book2,Book1}title_ws",
+            "facet.sort", FacetParams.FACET_SORT_COUNT),
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[1][@name='Book2']",
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[2][@name='Book1']",
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[3][@name='Book3']");
+
+    // order is by index, when facet.sort by index specified
+    assertQ(req("q", "*:*", FacetParams.FACET, "true", FacetParams.FACET_FIELD, "{!terms=Book3,Book2,Book1}title_ws",
+            "facet.sort", FacetParams.FACET_SORT_INDEX),
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[1][@name='Book1']",
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[2][@name='Book2']",
+        "//lst[@name='facet_fields']/lst[@name='title_ws']/int[3][@name='Book3']");
+  }
 }
 
diff --git a/solr/solr-ref-guide/src/faceting.adoc b/solr/solr-ref-guide/src/faceting.adoc
index 4827db0..efbb033 100644
--- a/solr/solr-ref-guide/src/faceting.adoc
+++ b/solr/solr-ref-guide/src/faceting.adoc
@@ -79,7 +79,7 @@ There are two options for this parameter.
 `index`::: Return the constraints sorted in their index order (lexicographic by indexed term). For terms in the ASCII range, this will be alphabetically sorted.
 --
 +
-The default is `count` if `facet.limit` is greater than 0, otherwise, the default is `index`.
+The default is `count` if `facet.limit` is greater than 0, otherwise, the default is `index`. Note that the default logic is changed when <<#limiting-facet-with-certain-terms>>
 
 `facet.limit`::
 This parameter specifies the maximum number of constraint counts (essentially, the number of facets for a field that are returned) that should be returned for the facet fields. A negative value means that Solr will return unlimited number of constraint counts.
@@ -616,7 +616,7 @@ To limit field facet with certain terms specify them comma separated with `terms
 
 `facet.field={!terms='alfa,betta,with\,with\',with space'}symbol`
 
-This parameter disables sorting, facet values are returned in the given order. 
+This local parameter overrides default logic for `facet.sort`. if `facet.sort` is omitted, facets are returned in the given terms order that might be changed with `index` and `count` values. Note: other parameters might not be fully supported when this parameter is supplied.   
 
 == Related Topics