SOLR-10480: fix offset param handling in JSON Facet API

This commit is contained in:
yonik 2017-04-25 22:56:44 -04:00
parent 2f6101b2ab
commit 1f77776937
3 changed files with 31 additions and 5 deletions

View File

@ -249,6 +249,8 @@ Bug Fixes
* SOLR-10520: child.facet.field doubled counts at least when rows>0. (Dr. Oleg Savrasov via Mikhail Khludnev)
* SOLR-10480: Full pagination in JSON Facet API using offset does not work. (yonik)
Other Changes
----------------------

View File

@ -217,9 +217,11 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
if (freq.limit >= 0) {
effectiveLimit = freq.limit;
if (fcontext.isShard()) {
// add over-request if this is a shard request
if (freq.overrequest == -1) {
effectiveLimit = (long) (effectiveLimit*1.1+4); // default: add 10% plus 4 (to overrequest for very small limits)
// add over-request if this is a shard request and if we have a small offset (large offsets will already be gathering many more buckets than needed)
if (freq.offset < 10) {
effectiveLimit = (long) (effectiveLimit * 1.1 + 4); // default: add 10% plus 4 (to overrequest for very small limits)
}
} else {
effectiveLimit += freq.overrequest;
}
@ -229,7 +231,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
final int sortMul = freq.sortDirection.getMultiplier();
int maxTopVals = (int) (effectiveLimit >= 0 ? Math.min(off + effectiveLimit, Integer.MAX_VALUE - 1) : Integer.MAX_VALUE - 1);
int maxTopVals = (int) (effectiveLimit >= 0 ? Math.min(freq.offset + effectiveLimit, Integer.MAX_VALUE - 1) : Integer.MAX_VALUE - 1);
maxTopVals = Math.min(maxTopVals, slotCardinality);
final SlotAcc sortAcc = this.sortAcc, indexOrderAcc = this.indexOrderAcc;
final BiPredicate<Slot,Slot> orderPredicate;
@ -315,7 +317,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
// if we are deep paging, we don't have to order the highest "offset" counts.
int collectCount = Math.max(0, queue.size() - off);
assert collectCount <= effectiveLimit;
assert collectCount <= maxTopVals;
int[] sortedSlots = new int[collectCount];
for (int i = collectCount - 1; i >= 0; i--) {
sortedSlots[i] = queue.pop().slot;

View File

@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
@ -1314,6 +1315,10 @@ public class TestJsonFacets extends SolrTestCaseHS {
doBigger( client, p );
}
private String getId(int id) {
return String.format(Locale.US, "%05d", id);
}
public void doBigger(Client client, ModifiableSolrParams p) throws Exception {
MacroExpander m = new MacroExpander(p.getMap());
@ -1332,7 +1337,7 @@ public class TestJsonFacets extends SolrTestCaseHS {
for (int i=0; i<ndocs; i++) {
Integer cat = r.nextInt(numCat);
Integer where = r.nextInt(numWhere);
client.add( sdoc("id", i, cat_s,cat, where_s, where) , null );
client.add( sdoc("id", getId(i), cat_s,cat, where_s, where) , null );
Map<Integer,List<Integer>> sub = model.get(cat);
if (sub == null) {
sub = new HashMap<>();
@ -1371,6 +1376,23 @@ public class TestJsonFacets extends SolrTestCaseHS {
);
}
client.testJQ(params(p, "q", "*:*"
, "json.facet", "{f1:{type:terms, field:id, limit:1, offset:990}}"
)
, "facets=={ 'count':" + ndocs + "," +
"'f1':{buckets:[{val:'00990',count:1}]}} "
);
for (int i=0; i<20; i++) {
int off = random().nextInt(ndocs);
client.testJQ(params(p, "q", "*:*", "off",Integer.toString(off)
, "json.facet", "{f1:{type:terms, field:id, limit:1, offset:${off}}}"
)
, "facets=={ 'count':" + ndocs + "," +
"'f1':{buckets:[{val:'" + getId(off) + "',count:1}]}} "
);
}
}
public void testTolerant() throws Exception {