You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by tf...@apache.org on 2014/08/08 03:25:05 UTC
svn commit: r1616656 - in /lucene/dev/branches/branch_4x: ./ solr/
solr/core/ solr/core/src/test/org/apache/solr/ solr/solrj/
solr/solrj/src/java/org/apache/solr/client/solrj/
solr/solrj/src/java/org/apache/solr/client/solrj/response/
solr/solrj/src/te...
Author: tflobbe
Date: Fri Aug 8 01:25:04 2014
New Revision: 1616656
URL: http://svn.apache.org/r1616656
Log:
SOLR-6283: Add support for Interval Faceting in SolrJ
Added:
lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/IntervalFacet.java
- copied unchanged from r1616628, lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/response/IntervalFacet.java
lucene/dev/branches/branch_4x/solr/solrj/src/test-files/solrj/sampleIntervalFacetsResponse.xml
- copied unchanged from r1616628, lucene/dev/trunk/solr/solrj/src/test-files/solrj/sampleIntervalFacetsResponse.xml
Modified:
lucene/dev/branches/branch_4x/ (props changed)
lucene/dev/branches/branch_4x/solr/ (props changed)
lucene/dev/branches/branch_4x/solr/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_4x/solr/core/ (props changed)
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/DistributedIntervalFacetingTest.java
lucene/dev/branches/branch_4x/solr/solrj/ (props changed)
lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java
lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java
lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/response/QueryResponseTest.java
Modified: lucene/dev/branches/branch_4x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/CHANGES.txt?rev=1616656&r1=1616655&r2=1616656&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/solr/CHANGES.txt Fri Aug 8 01:25:04 2014
@@ -106,6 +106,7 @@ New Features
* SOLR-6318: New "terms" QParser for efficiently filtering documents by a list of values. For
many values, it's more appropriate than a boolean query. (David Smiley)
+* SOLR-6283: Add support for Interval Faceting in SolrJ. (Tomás Fernández Löbbe)
Bug Fixes
----------------------
Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/DistributedIntervalFacetingTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/DistributedIntervalFacetingTest.java?rev=1616656&r1=1616655&r2=1616656&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/DistributedIntervalFacetingTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/DistributedIntervalFacetingTest.java Fri Aug 8 01:25:04 2014
@@ -2,9 +2,13 @@ package org.apache.solr;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.List;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.LuceneTestCase.Slow;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.response.IntervalFacet.Count;
+import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.junit.BeforeClass;
@@ -40,6 +44,61 @@ public class DistributedIntervalFaceting
del("*:*");
commit();
testRandom();
+ del("*:*");
+ commit();
+ testSolrJ();
+ }
+
+ private void testSolrJ() throws Exception {
+ indexr("id", "0", "test_i_dv", "0", "test_s_dv", "AAA");
+ indexr("id", "1", "test_i_dv", "1", "test_s_dv", "BBB");
+ indexr("id", "2", "test_i_dv", "2", "test_s_dv", "AAA");
+ indexr("id", "3", "test_i_dv", "3", "test_s_dv", "CCC");
+ commit();
+
+ QueryResponse response = controlClient.query(new SolrQuery("*:*"));
+ assertEquals(4, response.getResults().getNumFound());
+
+ SolrQuery q = new SolrQuery("*:*");
+ String[] intervals = new String[]{"[0,1)","[1,2)", "[2,3)", "[3,*)"};
+ q.addIntervalFacets("test_i_dv", intervals);
+ response = controlClient.query(q);
+ assertEquals(1, response.getIntervalFacets().size());
+ assertEquals("test_i_dv", response.getIntervalFacets().get(0).getField());
+ assertEquals(4, response.getIntervalFacets().get(0).getIntervals().size());
+ for (int i = 0; i < response.getIntervalFacets().get(0).getIntervals().size(); i++) {
+ Count count = response.getIntervalFacets().get(0).getIntervals().get(i);
+ assertEquals(intervals[i], count.getKey());
+ assertEquals(1, count.getCount());
+ }
+
+ q = new SolrQuery("*:*");
+ q.addIntervalFacets("test_i_dv", intervals);
+ q.addIntervalFacets("test_s_dv", new String[]{"{!key='AAA'}[AAA,AAA]", "{!key='BBB'}[BBB,BBB]", "{!key='CCC'}[CCC,CCC]"});
+ response = controlClient.query(q);
+ assertEquals(2, response.getIntervalFacets().size());
+
+ int stringIntervalIndex = "test_s_dv".equals(response.getIntervalFacets().get(0).getField())?0:1;
+
+ assertEquals("test_i_dv", response.getIntervalFacets().get(1-stringIntervalIndex).getField());
+ assertEquals("test_s_dv", response.getIntervalFacets().get(stringIntervalIndex).getField());
+
+ for (int i = 0; i < response.getIntervalFacets().get(1-stringIntervalIndex).getIntervals().size(); i++) {
+ Count count = response.getIntervalFacets().get(1-stringIntervalIndex).getIntervals().get(i);
+ assertEquals(intervals[i], count.getKey());
+ assertEquals(1, count.getCount());
+ }
+
+ List<Count> stringIntervals = response.getIntervalFacets().get(stringIntervalIndex).getIntervals();
+ assertEquals(3, stringIntervals.size());
+ assertEquals("AAA", stringIntervals.get(0).getKey());
+ assertEquals(2, stringIntervals.get(0).getCount());
+
+ assertEquals("BBB", stringIntervals.get(1).getKey());
+ assertEquals(1, stringIntervals.get(1).getCount());
+
+ assertEquals("CCC", stringIntervals.get(2).getKey());
+ assertEquals(1, stringIntervals.get(2).getCount());
}
private void testRandom() throws Exception {
Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java?rev=1616656&r1=1616655&r2=1616656&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/SolrQuery.java Fri Aug 8 01:25:04 2014
@@ -17,6 +17,13 @@
package org.apache.solr.client.solrj;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Pattern;
+
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.FacetParams;
import org.apache.solr.common.params.HighlightParams;
@@ -25,13 +32,6 @@ import org.apache.solr.common.params.Sta
import org.apache.solr.common.params.TermsParams;
import org.apache.solr.common.util.DateUtil;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
/**
* This is an augmented SolrParams with get/set/add fields for common fields used
@@ -273,7 +273,40 @@ public class SolrQuery extends Modifiabl
this.set(FacetParams.FACET, true);
return this;
}
-
+
+ /**
+ * Add Interval Faceting on a field. All intervals for the same field should be included
+ * in the same call to this method.
+ * For syntax documentation see <a href="https://wiki.apache.org/solr/SimpleFacetParameters#Interval_Faceting">Solr wiki</a>
+ *
+ * @param field the field to add facet intervals
+ * @param intervals Intervals to be used for faceting. It can be an empty array, but it can't
+ * be <code>null</code>
+ * @return this
+ */
+ public SolrQuery addIntervalFacets(String field, String[] intervals) {
+ if (intervals == null) {
+ throw new IllegalArgumentException("Can't add null intervals");
+ }
+ set(FacetParams.FACET, true);
+ add(FacetParams.FACET_INTERVAL, field);
+ for (String interval:intervals) {
+ add(String.format(Locale.ROOT, "f.%s.facet.interval.set", field), interval);
+ }
+ return this;
+ }
+
+ /**
+ * Remove all Interval Facets on a field
+ *
+ * @param field the field to remove from facet intervals
+ * @return Array of current intervals for <code>field</code>
+ */
+ public String[] removeIntervalFacets(String field) {
+ while(remove(FacetParams.FACET_INTERVAL, field)){};
+ return remove(String.format(Locale.ROOT, "f.%s.facet.interval.set", field));
+ }
+
/** get the facet fields
*
* @return string array of facet fields or null if not set/empty
@@ -317,6 +350,7 @@ public class SolrQuery extends Modifiabl
this.remove(FacetParams.FACET_SORT);
this.remove(FacetParams.FACET_ZEROS);
this.remove(FacetParams.FACET_PREFIX); // does not include the individual fields...
+ this.remove(FacetParams.FACET_INTERVAL); // does not remove interval parameters
}
return this;
}
Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java?rev=1616656&r1=1616655&r2=1616656&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/response/QueryResponse.java Fri Aug 8 01:25:04 2014
@@ -17,14 +17,19 @@
package org.apache.solr.client.solrj.response;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.beans.DocumentObjectBinder;
import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.params.CursorMarkParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
-import org.apache.solr.common.params.CursorMarkParams;
-
-import java.util.*;
/**
*
@@ -60,6 +65,7 @@ public class QueryResponse extends SolrR
private List<FacetField> _facetDates = null;
private List<RangeFacet> _facetRanges = null;
private NamedList<List<PivotField>> _facetPivot = null;
+ private List<IntervalFacet> _intervalFacets = null;
// Highlight Info
private Map<String,Map<String,List<String>>> _highlighting = null;
@@ -363,6 +369,20 @@ public class QueryResponse extends SolrR
_facetPivot.add( pf.getName(i), readPivots( (List<NamedList>)pf.getVal(i) ) );
}
}
+
+ //Parse interval facets
+ NamedList<NamedList<Object>> intervalsNL = (NamedList<NamedList<Object>>) info.get("facet_intervals");
+ if (intervalsNL != null) {
+ _intervalFacets = new ArrayList<>(intervalsNL.size());
+ for (Map.Entry<String, NamedList<Object>> intervalField : intervalsNL) {
+ String field = intervalField.getKey();
+ List<IntervalFacet.Count> counts = new ArrayList<IntervalFacet.Count>(intervalField.getValue().size());
+ for (Map.Entry<String, Object> interval : intervalField.getValue()) {
+ counts.add(new IntervalFacet.Count(interval.getKey(), (Integer)interval.getValue()));
+ }
+ _intervalFacets.add(new IntervalFacet(field, counts));
+ }
+ }
}
protected List<PivotField> readPivots( List<NamedList> list )
@@ -466,6 +486,10 @@ public class QueryResponse extends SolrR
return _facetPivot;
}
+ public List<IntervalFacet> getIntervalFacets() {
+ return _intervalFacets;
+ }
+
/** get
*
* @param name the name of the
Modified: lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java?rev=1616656&r1=1616655&r2=1616656&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/SolrQueryTest.java Fri Aug 8 01:25:04 2014
@@ -417,4 +417,36 @@ public class SolrQueryTest extends Lucen
solrQuery.addFacetQuery("field:value");
assertTrue("Adding a Facet Query should enable facets", solrQuery.getBool(FacetParams.FACET));
}
+
+ public void testFacetInterval() {
+ SolrQuery solrQuery = new SolrQuery();
+ solrQuery.addIntervalFacets("field1", new String[]{});
+ assertTrue(solrQuery.getBool(FacetParams.FACET));
+ assertEquals("field1", solrQuery.get(FacetParams.FACET_INTERVAL));
+
+ solrQuery.addIntervalFacets("field2", new String[]{"[1,10]"});
+ assertArrayEquals(new String[]{"field1", "field2"}, solrQuery.getParams(FacetParams.FACET_INTERVAL));
+ assertEquals("[1,10]", solrQuery.get("f.field2.facet.interval.set"));
+
+ solrQuery.addIntervalFacets("field3", new String[]{"[1,10]", "(10,100]", "(100,1000]", "(1000,*]"});
+ assertArrayEquals(new String[]{"field1", "field2", "field3"}, solrQuery.getParams(FacetParams.FACET_INTERVAL));
+ assertArrayEquals(new String[]{"[1,10]", "(10,100]", "(100,1000]", "(1000,*]"}, solrQuery.getParams("f.field3.facet.interval.set"));
+
+ //Validate adding more intervals for an existing field
+ solrQuery.addIntervalFacets("field2", new String[]{"[10,100]"});
+ assertArrayEquals(new String[]{"[1,10]", "[10,100]"}, solrQuery.getParams("f.field2.facet.interval.set"));
+
+ assertNull(solrQuery.removeIntervalFacets("field1"));
+ assertArrayEquals(new String[]{"field2", "field3", "field2"}, solrQuery.getParams(FacetParams.FACET_INTERVAL));
+ assertNull(solrQuery.getParams("f.field1.facet.interval.set"));
+
+ assertArrayEquals(new String[]{"[1,10]", "[10,100]"}, solrQuery.removeIntervalFacets("field2"));
+ assertArrayEquals(new String[]{"field3"}, solrQuery.getParams(FacetParams.FACET_INTERVAL));
+ assertNull(solrQuery.getParams("f.field2.facet.interval.set"));
+
+ assertArrayEquals(new String[]{"[1,10]", "(10,100]", "(100,1000]", "(1000,*]"}, solrQuery.removeIntervalFacets("field3"));
+ assertNull(solrQuery.getParams(FacetParams.FACET_INTERVAL));
+ assertNull(solrQuery.getParams("f.field3.facet.interval.set"));
+
+ }
}
Modified: lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/response/QueryResponseTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/response/QueryResponseTest.java?rev=1616656&r1=1616655&r2=1616656&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/response/QueryResponseTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/response/QueryResponseTest.java Fri Aug 8 01:25:04 2014
@@ -262,5 +262,49 @@ public class QueryResponseTest extends L
assertEquals("708_AR", documents.get(8).getFieldValue("acco_id"));
assertEquals("708_HI", documents.get(9).getFieldValue("acco_id"));
}
+
+
+ public void testIntervalFacetsResponse() throws Exception {
+ XMLResponseParser parser = new XMLResponseParser();
+ try(SolrResourceLoader loader = new SolrResourceLoader(null, null)) {
+ InputStream is = loader.openResource("solrj/sampleIntervalFacetsResponse.xml");
+ assertNotNull(is);
+ Reader in = new InputStreamReader(is, StandardCharsets.UTF_8);
+ NamedList<Object> response = parser.processResponse(in);
+ in.close();
+
+ QueryResponse qr = new QueryResponse(response, null);
+ assertNotNull(qr);
+ assertNotNull(qr.getIntervalFacets());
+ assertEquals(2, qr.getIntervalFacets().size());
+
+ IntervalFacet facet = qr.getIntervalFacets().get(0);
+ assertEquals("price", facet.getField());
+ assertEquals(3, facet.getIntervals().size());
+
+ assertEquals("[0,10]", facet.getIntervals().get(0).getKey());
+ assertEquals("(10,100]", facet.getIntervals().get(1).getKey());
+ assertEquals("(100,*]", facet.getIntervals().get(2).getKey());
+
+ assertEquals(3, facet.getIntervals().get(0).getCount());
+ assertEquals(4, facet.getIntervals().get(1).getCount());
+ assertEquals(9, facet.getIntervals().get(2).getCount());
+
+
+ facet = qr.getIntervalFacets().get(1);
+ assertEquals("popularity", facet.getField());
+ assertEquals(3, facet.getIntervals().size());
+
+ assertEquals("bad", facet.getIntervals().get(0).getKey());
+ assertEquals("average", facet.getIntervals().get(1).getKey());
+ assertEquals("good", facet.getIntervals().get(2).getKey());
+
+ assertEquals(3, facet.getIntervals().get(0).getCount());
+ assertEquals(10, facet.getIntervals().get(1).getCount());
+ assertEquals(2, facet.getIntervals().get(2).getCount());
+
+ }
+
+ }
}