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:39:21 UTC
[lucene-solr] branch branch_8x 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 branch_8x
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/branch_8x by this push:
new 513ba75 SOLR-13156: support facet.sort for facet.field={!terms=foo,bar}field
513ba75 is described below
commit 513ba75f3f801de80ea757bfb94e8dbdd0a0f7f0
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 fb9da3b..990413c 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -316,6 +316,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->count counts for the specified term values relative to the
+ * Computes the term->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