SOLR-7452: change terminology from _m missing-bucket to _p partial-bucket for refinement

This commit is contained in:
yonik 2017-03-28 19:52:51 -04:00 committed by Shalin Shekhar Mangar
parent 01520e393a
commit 0a6ba6fb0c
3 changed files with 16 additions and 17 deletions

View File

@ -530,13 +530,13 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
protected SimpleOrderedMap<Object> refineFacets() throws IOException {
List leaves = asList(fcontext.facetInfo.get("_l")); // We have not seen this bucket: do full faceting for this bucket, including all sub-facets
List<List> skip = asList(fcontext.facetInfo.get("_s")); // We have seen this bucket, so skip stats on it, and skip sub-facets except for the specified sub-facets that should calculate specified buckets.
List<List> missing = asList(fcontext.facetInfo.get("_m")); // We have not seen this bucket, do full faceting for this bucket, and most sub-facets... but some sub-facets should only visit specified buckets.
List<List> partial = asList(fcontext.facetInfo.get("_p")); // We have not seen this bucket, do full faceting for this bucket, and most sub-facets... but some sub-facets are partial and should only visit specified buckets.
// For leaf refinements, we do full faceting for each leaf bucket. Any sub-facets of these buckets will be fully evaluated. Because of this, we should never
// encounter leaf refinements that have sub-facets that return partial results.
SimpleOrderedMap<Object> res = new SimpleOrderedMap<>();
List<SimpleOrderedMap> bucketList = new ArrayList<>( leaves.size() + skip.size() + missing.size() );
List<SimpleOrderedMap> bucketList = new ArrayList<>( leaves.size() + skip.size() + partial.size() );
res.add("buckets", bucketList);
// TODO: an alternate implementations can fill all accs at once
@ -555,7 +555,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
}
// The only difference between skip and missing is the value of "skip" passed to refineBucket
for (List bucketAndFacetInfo : missing) {
for (List bucketAndFacetInfo : partial) {
assert bucketAndFacetInfo.size() == 2;
Object bucketVal = bucketAndFacetInfo.get(0);
Map<String,Object> facetInfo = (Map<String, Object>) bucketAndFacetInfo.get(1);

View File

@ -161,7 +161,7 @@ abstract class FacetRequestSortedMerger<FacetRequestT extends FacetRequestSorted
boolean thisMissing = mcontext.bucketWasMissing(); // Was this whole facet missing (i.e. inside a bucket that was missing)?
// TODO: add information in sub-shard response about dropped buckets (i.e. not all returned due to limit)
// If we know we've seen all the buckets from a shard, then we don't have to add to leafBuckets or missingBuckets, only skipBuckets
// If we know we've seen all the buckets from a shard, then we don't have to add to leafBuckets or partialBuckets, only skipBuckets
boolean isCommandPartial = freq.returnsPartial();
boolean returnedAllBuckets = !isCommandPartial && !thisMissing; // did the shard return all of the possible buckets?
@ -189,7 +189,7 @@ abstract class FacetRequestSortedMerger<FacetRequestT extends FacetRequestSorted
}
ArrayList<Object> leafBuckets = null; // "_l" missing buckets specified by bucket value only (no need to specify anything further)
ArrayList<Object> missingBuckets = null; // "_m" missing buckets that need to specify values for partial facets.. each entry is [bucketval, subs]
ArrayList<Object> partialBuckets = null; // "_p" missing buckets that have a partial sub-facet that need to specify those bucket values... each entry is [bucketval, subs]
ArrayList<Object> skipBuckets = null; // "_s" present buckets that we need to recurse into because children facets have refinement requirements. each entry is [bucketval, subs]
for (FacetBucket bucket : bucketList) {
@ -208,12 +208,12 @@ abstract class FacetRequestSortedMerger<FacetRequestT extends FacetRequestSorted
mcontext.setBucketWasMissing(prev);
if (bucketRefinement != null) {
if (missingBuckets==null) missingBuckets = new ArrayList<>();
missingBuckets.add( Arrays.asList(bucket.bucketValue, bucketRefinement) );
if (partialBuckets==null) partialBuckets = new ArrayList<>();
partialBuckets.add( Arrays.asList(bucket.bucketValue, bucketRefinement) );
}
}
// if we didn't add to "_m" (missing), then we should add to "_l" (leaf missing)
// if we didn't add to "_p" (missing with partial sub-facets), then we should add to "_l" (missing leaf)
if (bucketRefinement == null) {
if (leafBuckets == null) leafBuckets = new ArrayList<>();
leafBuckets.add(bucket.bucketValue);
@ -231,12 +231,12 @@ abstract class FacetRequestSortedMerger<FacetRequestT extends FacetRequestSorted
}
// TODO: what if we don't need to refine any variable buckets, but we do need to contribute to numBuckets, missing, allBuckets, etc...
// because we were "missing". That will be handled at a higher level (i.e. we'll be in someone's missing bucket?)
// because we were "partial". That will be handled at a higher level (i.e. we'll be in someone's missing bucket?)
// TODO: test with a sub-facet with a limit of 0 and something like a missing bucket
if (leafBuckets != null || missingBuckets != null || skipBuckets != null) {
if (leafBuckets != null || partialBuckets != null || skipBuckets != null) {
refinement = new HashMap<>(3);
if (leafBuckets != null) refinement.put("_l",leafBuckets);
if (missingBuckets != null) refinement.put("_m", missingBuckets);
if (partialBuckets != null) refinement.put("_p", partialBuckets);
if (skipBuckets != null) refinement.put("_s", skipBuckets);
}

View File

@ -36,7 +36,6 @@ import org.noggit.ObjectBuilder;
public class TestJsonFacetRefinement extends SolrTestCaseHS {
private static SolrInstances servers; // for distributed testing
private static int origTableSize;
@BeforeClass
public static void beforeTests() throws Exception {
@ -209,13 +208,13 @@ public class TestJsonFacetRefinement extends SolrTestCaseHS {
"}"
);
// for testing missing _m, we need a partial facet within a partial facet
// for testing partial _p, we need a partial facet within a partial facet
doTestRefine("{top:{type:terms, field:Afield, refine:true, limit:1, facet:{x : {type:terms, field:X, limit:1, refine:true} } } }",
"{top: {buckets:[{val:'A', count:2, x:{buckets:[{val:x1, count:5},{val:x2, count:3}]} } ] } }",
"{top: {buckets:[{val:'B', count:1, x:{buckets:[{val:x2, count:4},{val:x3, count:2}]} } ] } }",
null,
"=={top: {" +
"_m:[ ['A' , {x:{_l:[x1]}} ] ]" +
"_p:[ ['A' , {x:{_l:[x1]}} ] ]" +
" } " +
"}"
);
@ -329,7 +328,7 @@ public class TestJsonFacetRefinement extends SolrTestCaseHS {
"}"
);
// test that sibling facets and stats are included for _m buckets, but skipped for _s buckets
// test that sibling facets and stats are included for _p buckets, but skipped for _s buckets
client.testJQ(params(p, "q", "*:*",
"json.facet", "{" +
" ab :{type:terms, field:${cat_s}, limit:1, overrequest:0, refine:true, facet:{ xy:{type:terms, field:${xy_s}, limit:1, overrequest:0, refine:true}, qq:{query:'*:*'},ww:'sum(${num_d})' }}" +
@ -339,9 +338,9 @@ public class TestJsonFacetRefinement extends SolrTestCaseHS {
"}"
)
, "facets=={ count:8" +
", ab:{ buckets:[ {val:A, count:4, xy:{buckets:[ {val:X,count:3}]} ,qq:{count:4}, ww:4.0 }] }" + // make sure qq and ww are included for _m buckets
", ab:{ buckets:[ {val:A, count:4, xy:{buckets:[ {val:X,count:3}]} ,qq:{count:4}, ww:4.0 }] }" + // make sure qq and ww are included for _p buckets
", allf:{ buckets:[ {count:8, val:all, cat:{buckets:[{val:A,count:4}]} ,qq:{count:8}, ww:2.0 }] }" + // make sure qq and ww are excluded (not calculated again in another phase) for _s buckets
", ab2:{ buckets:[ {val:A, count:4, xy:{buckets:[ {val:X,count:3}]} ,qq:{count:4}, ww:4.0 }] }" + // make sure qq and ww are included for _m buckets
", ab2:{ buckets:[ {val:A, count:4, xy:{buckets:[ {val:X,count:3}]} ,qq:{count:4}, ww:4.0 }] }" + // make sure qq and ww are included for _p buckets
", allf2:{ buckets:[ {count:8, val:all, cat:{buckets:[{val:A,count:4}]} ,qq:{count:8}, ww:2.0 }] }" + // make sure qq and ww are excluded (not calculated again in another phase) for _s buckets
"}"
);