SOLR-3783: Fixed Pivot Faceting to work with facet.missing=true

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1387824 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Chris M. Hostetter 2012-09-20 00:17:57 +00:00
parent c529308734
commit 52d9fdb780
3 changed files with 124 additions and 27 deletions

View File

@ -256,6 +256,8 @@ Bug Fixes
fixes some bugs related to xinclude and fieldTypes. fixes some bugs related to xinclude and fieldTypes.
(Amit Nithian, hossman) (Amit Nithian, hossman)
* SOLR-3783: Fixed Pivot Faceting to work with facet.missing=true (hossman)
Other Changes Other Changes
---------------------- ----------------------

View File

@ -32,6 +32,7 @@ import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.FieldType; import org.apache.solr.schema.FieldType;
import org.apache.lucene.search.Query; import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.index.Term; import org.apache.lucene.index.Term;
import java.io.IOException; import java.io.IOException;
@ -103,22 +104,38 @@ public class PivotFacetHelper
for (Map.Entry<String, Integer> kv : superFacets) { for (Map.Entry<String, Integer> kv : superFacets) {
// Only sub-facet if parent facet has positive count - still may not be any values for the sub-field though // Only sub-facet if parent facet has positive count - still may not be any values for the sub-field though
if (kv.getValue() >= minMatch ) { if (kv.getValue() >= minMatch ) {
// don't reuse the same BytesRef each time since we will be constructing Term
// objects that will most likely be cached. // may be null when using facet.missing
BytesRef termval = new BytesRef(); final String fieldValue = kv.getKey();
ftype.readableToIndexed(kv.getKey(), termval);
// don't reuse the same BytesRef each time since we will be
// constructing Term objects used in TermQueries that may be cached.
BytesRef termval = null;
SimpleOrderedMap<Object> pivot = new SimpleOrderedMap<Object>(); SimpleOrderedMap<Object> pivot = new SimpleOrderedMap<Object>();
pivot.add( "field", field ); pivot.add( "field", field );
pivot.add( "value", ftype.toObject(sfield, termval) ); if (null == fieldValue) {
pivot.add( "value", null );
} else {
termval = new BytesRef();
ftype.readableToIndexed(fieldValue, termval);
pivot.add( "value", ftype.toObject(sfield, termval) );
}
pivot.add( "count", kv.getValue() ); pivot.add( "count", kv.getValue() );
if( subField == null ) { if( subField == null ) {
values.add( pivot ); values.add( pivot );
} }
else { else {
Query query = new TermQuery(new Term(field, termval)); DocSet subset = null;
DocSet subset = searcher.getDocSet(query, docs); if ( null == termval ) {
DocSet hasVal = searcher.getDocSet
(new TermRangeQuery(field, null, null, false, false));
subset = docs.andNot(hasVal);
} else {
Query query = new TermQuery(new Term(field, termval));
subset = searcher.getDocSet(query, docs);
}
SimpleFacets sf = getFacetImplementation(rb.req, subset, rb.req.getParams()); SimpleFacets sf = getFacetImplementation(rb.req, subset, rb.req.getParams());
NamedList<Integer> nl = sf.getTermCounts(subField); NamedList<Integer> nl = sf.getTermCounts(subField);
@ -134,6 +151,7 @@ public class PivotFacetHelper
fnames.push( nextField ); fnames.push( nextField );
return values; return values;
} }
// TODO: This is code from various patches to support distributed search. // TODO: This is code from various patches to support distributed search.
// Some parts may be helpful for whoever implements distributed search. // Some parts may be helpful for whoever implements distributed search.
// //

View File

@ -939,8 +939,15 @@ abstract public class SolrExampleTests extends SolrJettyTestBase
} }
@Test @Test
public void testPivotFacet() throws Exception public void testPivotFacets() throws Exception {
{ doPivotFacetTest(false);
}
public void testPivotFacetsMissing() throws Exception {
doPivotFacetTest(true);
}
private void doPivotFacetTest(boolean missing) throws Exception {
SolrServer server = getSolrServer(); SolrServer server = getSolrServer();
// Empty the database... // Empty the database...
@ -961,13 +968,14 @@ abstract public class SolrExampleTests extends SolrJettyTestBase
docs.add( makeTestDoc( "id", id++, "features", "bbb", "cat", "b", "inStock", true ) ); docs.add( makeTestDoc( "id", id++, "features", "bbb", "cat", "b", "inStock", true ) );
docs.add( makeTestDoc( "id", id++, "features", "bbb", "cat", "b", "inStock", false ) ); docs.add( makeTestDoc( "id", id++, "features", "bbb", "cat", "b", "inStock", false ) );
docs.add( makeTestDoc( "id", id++, "features", "bbb", "cat", "b", "inStock", true ) ); docs.add( makeTestDoc( "id", id++, "features", "bbb", "cat", "b", "inStock", true ) );
docs.add( makeTestDoc( "id", id++ ) ); // something not matching docs.add( makeTestDoc( "id", id++, "cat", "b" ) ); // something not matching all fields
server.add( docs ); server.add( docs );
server.commit(); server.commit();
SolrQuery query = new SolrQuery( "*:*" ); SolrQuery query = new SolrQuery( "*:*" );
query.addFacetPivotField("features,cat", "cat,features", "features,cat,inStock" ); query.addFacetPivotField("features,cat", "cat,features", "features,cat,inStock" );
query.setFacetMinCount( 0 ); query.setFacetMinCount( 0 );
query.setFacetMissing( missing );
query.setRows( 0 ); query.setRows( 0 );
QueryResponse rsp = server.query( query ); QueryResponse rsp = server.query( query );
@ -991,10 +999,12 @@ abstract public class SolrExampleTests extends SolrJettyTestBase
// features=aaa (5) // features=aaa (5)
// cat=a (3) // cat=a (3)
// cat=b (2) // cat=b (2)
// features missing (1)
List<PivotField> pivot = pivots.getVal( 0 ); // cat=b (1)
assertEquals( "features,cat", pivots.getName( 0 ) ); assertEquals( "features,cat", pivots.getName( 0 ) );
assertEquals( 2, pivot.size() ); List<PivotField> pivot = pivots.getVal( 0 );
assertEquals( missing ? 3 : 2, pivot.size() );
PivotField ff = pivot.get( 0 ); PivotField ff = pivot.get( 0 );
assertEquals( "features", ff.getField() ); assertEquals( "features", ff.getField() );
@ -1007,27 +1017,72 @@ abstract public class SolrExampleTests extends SolrJettyTestBase
assertEquals( 4, counts.get(0).getCount() ); assertEquals( 4, counts.get(0).getCount() );
assertEquals( "a", counts.get(1).getValue() ); assertEquals( "a", counts.get(1).getValue() );
assertEquals( 2, counts.get(1).getCount() ); assertEquals( 2, counts.get(1).getCount() );
// PIVOT: cat,features
// cat=b (6)
// features=bbb (4)
// features=aaa (2)
// cat=a (5)
// features=aaa (3)
// features=bbb (2)
ff = pivot.get( 1 ); ff = pivot.get( 1 );
assertEquals( "features", ff.getField() ); assertEquals( "features", ff.getField() );
assertEquals( "aaa", ff.getValue() ); assertEquals( "aaa", ff.getValue() );
assertEquals( 5, ff.getCount() ); assertEquals( 5, ff.getCount() );
counts = ff.getPivot(); counts = ff.getPivot();
assertEquals( 2, counts.size() ); assertEquals( 2, counts.size() );
assertEquals( "cat", counts.get(0).getField() );
assertEquals( "a", counts.get(0).getValue() ); assertEquals( "a", counts.get(0).getValue() );
assertEquals( 3, counts.get(0).getCount() ); assertEquals( 3, counts.get(0).getCount() );
assertEquals( "b", counts.get(1).getValue() ); assertEquals( "b", counts.get(1).getValue() );
assertEquals( 2, counts.get(1).getCount() ); assertEquals( 2, counts.get(1).getCount() );
if (missing) {
ff = pivot.get( 2 );
assertEquals( "features", ff.getField() );
assertEquals( null, ff.getValue() );
assertEquals( 1, ff.getCount() );
counts = ff.getPivot();
assertEquals( 1, counts.size() );
assertEquals( "cat", counts.get(0).getField() );
assertEquals( "b", counts.get(0).getValue() );
assertEquals( 1, counts.get(0).getCount() );
}
// PIVOT: cat,features
// cat=b (7)
// features=bbb (4)
// features=aaa (2)
// features missing (1)
// cat=a (5)
// features=aaa (3)
// features=bbb (2)
assertEquals( "cat,features", pivots.getName( 1 ) );
pivot = pivots.getVal( 1 );
assertEquals( 2, pivot.size() );
ff = pivot.get( 0 );
assertEquals( "cat", ff.getField() );
assertEquals( "b", ff.getValue() );
assertEquals( 7, ff.getCount() );
counts = ff.getPivot();
assertEquals( missing ? 3 : 2, counts.size() );
assertEquals( "features", counts.get(0).getField() );
assertEquals( "bbb", counts.get(0).getValue() );
assertEquals( 4, counts.get(0).getCount() );
assertEquals( "aaa", counts.get(1).getValue() );
assertEquals( 2, counts.get(1).getCount() );
if ( missing ) {
assertEquals( null, counts.get(2).getValue() );
assertEquals( 1, counts.get(2).getCount() );
}
ff = pivot.get( 1 );
assertEquals( "cat", ff.getField() );
assertEquals( "a", ff.getValue() );
assertEquals( 5, ff.getCount() );
counts = ff.getPivot();
assertEquals( 2, counts.size() );
assertEquals( "features", counts.get(0).getField() );
assertEquals( "aaa", counts.get(0).getValue() );
assertEquals( 3, counts.get(0).getCount() );
assertEquals( "bbb", counts.get(1).getValue() );
assertEquals( 2, counts.get(1).getCount() );
// Three deep: // Three deep:
// PIVOT: features,cat,inStock // PIVOT: features,cat,inStock
// features=bbb (6) // features=bbb (6)
@ -1044,10 +1099,13 @@ abstract public class SolrExampleTests extends SolrJettyTestBase
// cat=b (2) // cat=b (2)
// inStock=false (1) // inStock=false (1)
// inStock=true (1) // inStock=true (1)
// features missing (1)
pivot = pivots.getVal( 2 ); // cat=b (1)
// inStock missing (1)
assertEquals( "features,cat,inStock", pivots.getName( 2 ) ); assertEquals( "features,cat,inStock", pivots.getName( 2 ) );
assertEquals( 2, pivot.size() ); pivot = pivots.getVal( 2 );
assertEquals( missing ? 3 : 2, pivot.size() );
PivotField p = pivot.get( 1 ).getPivot().get(0); // get(1) should be features=AAAA, then get(0) should be cat=a PivotField p = pivot.get( 1 ).getPivot().get(0); // get(1) should be features=AAAA, then get(0) should be cat=a
assertEquals( "cat", p.getField() ); assertEquals( "cat", p.getField() );
assertEquals( "a", p.getValue() ); assertEquals( "a", p.getValue() );
@ -1057,6 +1115,25 @@ abstract public class SolrExampleTests extends SolrJettyTestBase
assertEquals( "inStock", counts.get(0).getField() ); assertEquals( "inStock", counts.get(0).getField() );
assertEquals( Boolean.TRUE, counts.get(0).getValue() ); assertEquals( Boolean.TRUE, counts.get(0).getValue() );
assertEquals( 2, counts.get(0).getCount() ); assertEquals( 2, counts.get(0).getCount() );
if (missing) {
p = pivot.get( 2 );
assertEquals( "features", p.getField() );
assertEquals( null, p.getValue() );
assertEquals( 1, p.getCount() );
assertEquals( 1, p.getPivot().size() );
p = p.getPivot().get(0);
assertEquals( "cat", p.getField() );
assertEquals( "b", p.getValue() );
assertEquals( 1, p.getCount() );
assertEquals( 1, p.getPivot().size() );
p = p.getPivot().get(0);
assertEquals( "inStock", p.getField() );
assertEquals( null, p.getValue() );
assertEquals( 1, p.getCount() );
assertEquals( null, p.getPivot() );
}
} }
public static SolrInputDocument makeTestDoc( Object ... kvp ) public static SolrInputDocument makeTestDoc( Object ... kvp )