You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by md...@apache.org on 2021/07/15 19:43:02 UTC
[solr] branch main updated: SOLR-15531: significantTerms streaming
function should not fail on empty collections (#212)
This is an automated email from the ASF dual-hosted git repository.
mdrob pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 5346024 SOLR-15531: significantTerms streaming function should not fail on empty collections (#212)
5346024 is described below
commit 5346024eefc7139de215ea24ccc551d624280144
Author: Benedikt Arnold <be...@benarnold.de>
AuthorDate: Thu Jul 15 21:42:52 2021 +0200
SOLR-15531: significantTerms streaming function should not fail on empty collections (#212)
---
solr/CHANGES.txt | 2 +
.../solr/search/SignificantTermsQParserPlugin.java | 33 +++++
.../search/SignificantTermsQParserPluginTest.java | 135 +++++++++++++++++++--
3 files changed, 160 insertions(+), 10 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 6fcd5da..e9cdb6f 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -383,6 +383,8 @@ Bug Fixes
* SOLR-15311: Support async parameter in MODIFYCOLLECTION
(Nazerke Seidan, Christine Poerschke, David Smiley)
+* SOLR-15531: SignificantTerms streaming function should not fail on empty collections (Benedikt Arnold via Mike Drob)
+
Other Changes
---------------------
(No changes)
diff --git a/solr/core/src/java/org/apache/solr/search/SignificantTermsQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/SignificantTermsQParserPlugin.java
index 7415e67..1aea7a4 100644
--- a/solr/core/src/java/org/apache/solr/search/SignificantTermsQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/SignificantTermsQParserPlugin.java
@@ -89,10 +89,43 @@ public class SignificantTermsQParserPlugin extends QParserPlugin {
@Override
public DelegatingCollector getAnalyticsCollector(ResponseBuilder rb, IndexSearcher searcher) {
+ if (searcher.getIndexReader().maxDoc() <= 0) {
+ return new NoOpTermsCollector(rb);
+ }
return new SignifcantTermsCollector(rb, searcher, field, numTerms, minDocs, maxDocs, minTermLength);
}
}
+ private static class NoOpTermsCollector extends DelegatingCollector {
+ private ResponseBuilder rb;
+
+ private NoOpTermsCollector(ResponseBuilder rb) {
+ this.rb = rb;
+ }
+
+ @Override
+ public void collect(int doc) throws IOException {
+ }
+
+ @Override
+ public void finish() throws IOException {
+ List<String> outTerms = new ArrayList<>();
+ List<Integer> outFreq = new ArrayList<>();
+ List<Integer> outQueryFreq = new ArrayList<>();
+ List<Double> scores = new ArrayList<>();
+
+ LinkedHashMap<String, Object> response = new LinkedHashMap<>();
+
+ rb.rsp.add(NAME, response);
+
+ response.put("numDocs", 0);
+ response.put("sterms", outTerms);
+ response.put("scores", scores);
+ response.put("docFreq", outFreq);
+ response.put("queryDocFreq", outQueryFreq);
+ }
+ }
+
private static class SignifcantTermsCollector extends DelegatingCollector {
private String field;
diff --git a/solr/core/src/test/org/apache/solr/search/SignificantTermsQParserPluginTest.java b/solr/core/src/test/org/apache/solr/search/SignificantTermsQParserPluginTest.java
index bcd66da..b8cdd01 100644
--- a/solr/core/src/test/org/apache/solr/search/SignificantTermsQParserPluginTest.java
+++ b/solr/core/src/test/org/apache/solr/search/SignificantTermsQParserPluginTest.java
@@ -17,19 +17,134 @@
package org.apache.solr.search;
+import org.apache.commons.io.FileUtils;
import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.params.MapSolrParams;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.core.SolrCore;
+import org.apache.solr.handler.component.ResponseBuilder;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.update.AddUpdateCommand;
+import org.apache.solr.update.CommitUpdateCommand;
+import org.apache.solr.update.DeleteUpdateCommand;
+import org.apache.solr.util.RefCounted;
+import org.junit.BeforeClass;
import org.junit.Test;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
public class SignificantTermsQParserPluginTest extends SolrTestCaseJ4 {
- /**
- * Test the backwards compatibility for a typo in the SignificantTermsQParserPlugin. It will fail if the backwards
- * compatibility is broken.
- */
- @Test
- public void testQParserBackwardsCompatibility() {
- assertEquals("significantTerms", SignificantTermsQParserPlugin.NAME);
- assertEquals(SignificantTermsQParserPlugin.class,
- QParserPlugin.standardPlugins.get(SignificantTermsQParserPlugin.NAME).getClass());
- }
+ @BeforeClass
+ public static void setUpCore() throws Exception {
+ String tmpSolrHome = createTempDir().toFile().getAbsolutePath();
+ FileUtils.copyDirectory(new File(TEST_HOME()), new File(tmpSolrHome).getAbsoluteFile());
+ initCore("solrconfig.xml", "schema.xml", new File(tmpSolrHome).getAbsolutePath());
+ }
+
+ /**
+ * Test the backwards compatibility for a typo in the SignificantTermsQParserPlugin. It will fail if the backwards
+ * compatibility is broken.
+ */
+ @Test
+ public void testQParserBackwardsCompatibility() {
+ assertEquals("significantTerms", SignificantTermsQParserPlugin.NAME);
+ assertEquals(SignificantTermsQParserPlugin.class,
+ QParserPlugin.standardPlugins.get(SignificantTermsQParserPlugin.NAME).getClass());
+ }
+
+ @Test
+ public void testEmptyCollectionDoesNotThrow() throws Exception {
+ SolrCore emptyCore = h.getCore();
+ QParserPlugin qParserPlugin = QParserPlugin.standardPlugins.get(SignificantTermsQParserPlugin.NAME);
+ Map<String, String> params = new HashMap<>();
+ params.put("field", "cat");
+ QParser parser = qParserPlugin.createParser("", new MapSolrParams(params), new MapSolrParams(new HashMap<>()), null);
+ AnalyticsQuery query = (AnalyticsQuery) parser.parse();
+ SolrQueryResponse resp = new SolrQueryResponse();
+
+ RefCounted<SolrIndexSearcher> searcher = emptyCore.getSearcher();
+ try {
+ DelegatingCollector analyticsCollector = query.getAnalyticsCollector(new ResponseBuilder(null, resp, Collections.emptyList()), searcher.get());
+ assertNotNull(analyticsCollector);
+ analyticsCollector.finish();
+ LinkedHashMap<String, Object> expectedValues = new LinkedHashMap<>();
+ expectedValues.put("numDocs", 0);
+ expectedValues.put("sterms", new ArrayList<String>());
+ expectedValues.put("scores", new ArrayList<Integer>());
+ expectedValues.put("docFreq", new ArrayList<Integer>());
+ expectedValues.put("queryDocFreq", new ArrayList<Double>());
+ assertEquals(expectedValues, resp.getValues().get("significantTerms"));
+ } finally {
+ searcher.decref();
+ }
+
+ }
+
+ @Test
+ public void testCollectionWithDocuments() throws Exception {
+ SolrCore dataCore = h.getCore();
+ addTestDocs(dataCore);
+
+ QParserPlugin qParserPlugin = QParserPlugin.standardPlugins.get(SignificantTermsQParserPlugin.NAME);
+ Map<String, String> params = new HashMap<>();
+ params.put("field", "cat");
+ QParser parser = qParserPlugin.createParser("", new MapSolrParams(params), new MapSolrParams(new HashMap<>()), null);
+ AnalyticsQuery query = (AnalyticsQuery) parser.parse();
+ SolrQueryResponse resp = new SolrQueryResponse();
+
+ ResponseBuilder responseBuilder = new ResponseBuilder(null, resp, Collections.emptyList());
+ RefCounted<SolrIndexSearcher> searcher = dataCore.getSearcher();
+ try {
+
+ DelegatingCollector analyticsCollector = query.getAnalyticsCollector(responseBuilder, searcher.get());
+ assertNotNull(analyticsCollector);
+ analyticsCollector.finish();
+
+ LinkedHashMap<String, Object> expectedValues = new LinkedHashMap<>();
+ expectedValues.put("numDocs", 1);
+ expectedValues.put("sterms", new ArrayList<String>());
+ expectedValues.put("scores", new ArrayList<Integer>());
+ expectedValues.put("docFreq", new ArrayList<Integer>());
+ expectedValues.put("queryDocFreq", new ArrayList<Double>());
+
+ assertEquals(expectedValues, resp.getValues().get("significantTerms"));
+
+ } finally {
+ searcher.decref();
+ }
+
+ deleteTestDocs(dataCore);
+ }
+
+ private void addTestDocs(SolrCore core) throws IOException {
+ SolrQueryRequest coreReq = new LocalSolrQueryRequest(core, new ModifiableSolrParams());
+ AddUpdateCommand cmd = new AddUpdateCommand(coreReq);
+ cmd.solrDoc = new SolrInputDocument();
+ cmd.solrDoc.addField("id", "1");
+ cmd.solrDoc.addField("cat", "foo");
+ core.getUpdateHandler().addDoc(cmd);
+
+ core.getUpdateHandler().commit(new CommitUpdateCommand(coreReq, true));
+ coreReq.close();
+ }
+
+ private void deleteTestDocs(SolrCore core) throws IOException {
+ SolrQueryRequest coreReq = new LocalSolrQueryRequest(core, new ModifiableSolrParams());
+ DeleteUpdateCommand cmd = new DeleteUpdateCommand(coreReq);
+ cmd.id = "1";
+ core.getUpdateHandler().delete(cmd);
+ core.getUpdateHandler().commit(new CommitUpdateCommand(coreReq, true));
+ coreReq.close();
+ }
+
}