mirror of https://github.com/apache/lucene.git
SOLR-11775: return long val for facet count in json facet
* Long value is returned for any count related to json facets irrespective of number of shards
This commit is contained in:
parent
71d335ff68
commit
36b280bd0a
|
@ -579,11 +579,11 @@ public class SimpleFacets {
|
|||
|
||||
List<NamedList<Object>> buckets = (List<NamedList<Object>>)res.get("buckets");
|
||||
for(NamedList<Object> b : buckets) {
|
||||
counts.add(b.get("val").toString(), (Integer)b.get("count"));
|
||||
counts.add(b.get("val").toString(), ((Number)b.get("count")).intValue());
|
||||
}
|
||||
if(missing) {
|
||||
NamedList<Object> missingCounts = (NamedList<Object>) res.get("missing");
|
||||
counts.add(null, (Integer)missingCounts.get("count"));
|
||||
counts.add(null, ((Number)missingCounts.get("count")).intValue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -50,7 +50,7 @@ public abstract class AggValueSource extends ValueSource {
|
|||
}
|
||||
|
||||
// TODO: make abstract
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED " + name + " " + this);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ public class AvgAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
|
||||
if (vs instanceof FieldNameValueSource) {
|
||||
|
|
|
@ -24,7 +24,7 @@ public class CountAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
return new CountSlotArrAcc(fcontext, numSlots);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ public class CountValsAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
if (vs instanceof FieldNameValueSource) {
|
||||
String field = ((FieldNameValueSource)vs).getFieldName();
|
||||
|
|
|
@ -108,7 +108,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
|
|||
|
||||
/** This is used to create accs for second phase (or to create accs for all aggs) */
|
||||
@Override
|
||||
protected void createAccs(int docCount, int slotCount) throws IOException {
|
||||
protected void createAccs(long docCount, int slotCount) throws IOException {
|
||||
if (accMap == null) {
|
||||
accMap = new LinkedHashMap<>();
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
|
|||
IntFunction<Comparable> bucketValFromSlotNumFunc,
|
||||
Function<Comparable, String> fieldQueryValFunc) throws IOException {
|
||||
assert this.sortAcc != null;
|
||||
int numBuckets = 0;
|
||||
long numBuckets = 0;
|
||||
|
||||
final int off = fcontext.isShard() ? 0 : (int) freq.offset;
|
||||
|
||||
|
@ -347,7 +347,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
|
|||
|
||||
// screen out buckets not matching mincount
|
||||
if (effectiveMincount > 0) {
|
||||
int count = countAcc.getCount(slotNum);
|
||||
long count = countAcc.getCount(slotNum);
|
||||
if (count < effectiveMincount) {
|
||||
if (count > 0)
|
||||
numBuckets++; // Still increment numBuckets as long as we have some count. This is for consistency between distrib and non-distrib mode.
|
||||
|
@ -387,7 +387,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
|
|||
}
|
||||
|
||||
FacetDebugInfo fdebug = fcontext.getDebugInfo();
|
||||
if (fdebug != null) fdebug.putInfoItem("numBuckets", (long) numBuckets);
|
||||
if (fdebug != null) fdebug.putInfoItem("numBuckets", numBuckets);
|
||||
|
||||
if (freq.allBuckets) {
|
||||
SimpleOrderedMap<Object> allBuckets = new SimpleOrderedMap<>();
|
||||
|
@ -507,7 +507,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
|
|||
/** Helper method used solely when looping over buckets to be returned in findTopSlots */
|
||||
private void fillBucketFromSlot(SimpleOrderedMap<Object> target, Slot slot,
|
||||
SlotAcc resortAcc) throws IOException {
|
||||
final int count = countAcc.getCount(slot.slot);
|
||||
final long count = countAcc.getCount(slot.slot);
|
||||
target.add("count", count);
|
||||
if (count <= 0 && !freq.processEmpty) return;
|
||||
|
||||
|
@ -645,14 +645,14 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void processStats(SimpleOrderedMap<Object> bucket, Query bucketQ, DocSet docs, int docCount) throws IOException {
|
||||
protected void processStats(SimpleOrderedMap<Object> bucket, Query bucketQ, DocSet docs, long docCount) throws IOException {
|
||||
if (docCount == 0 && !freq.processEmpty || freq.getFacetStats().size() == 0) {
|
||||
bucket.add("count", docCount);
|
||||
return;
|
||||
}
|
||||
createAccs(docCount, 1);
|
||||
assert null != bucketQ;
|
||||
int collected = collect(docs, 0, slotNum -> { return new SlotContext(bucketQ); });
|
||||
long collected = collect(docs, 0, slotNum -> { return new SlotContext(bucketQ); });
|
||||
|
||||
// countAcc.incrementCount(0, collected); // should we set the counton the acc instead of just passing it?
|
||||
|
||||
|
@ -661,7 +661,7 @@ abstract class FacetFieldProcessor extends FacetProcessor<FacetField> {
|
|||
}
|
||||
|
||||
// overrides but with different signature!
|
||||
private void addStats(SimpleOrderedMap<Object> target, int count, int slotNum) throws IOException {
|
||||
private void addStats(SimpleOrderedMap<Object> target, long count, int slotNum) throws IOException {
|
||||
target.add("count", count);
|
||||
if (count > 0 || freq.processEmpty) {
|
||||
for (SlotAcc acc : accs) {
|
||||
|
|
|
@ -57,8 +57,8 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor {
|
|||
static final float LOAD_FACTOR = 0.7f;
|
||||
|
||||
long[] vals;
|
||||
int[] counts; // maintain the counts here since we need them to tell if there was actually a value anyway
|
||||
int[] oldToNewMapping;
|
||||
long[] counts; // maintain the counts here since we need them to tell if there was actually a value anyway
|
||||
long[] oldToNewMapping;
|
||||
|
||||
int cardinality;
|
||||
int threshold;
|
||||
|
@ -66,7 +66,7 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor {
|
|||
/** sz must be a power of two */
|
||||
LongCounts(int sz) {
|
||||
vals = new long[sz];
|
||||
counts = new int[sz];
|
||||
counts = new long[sz];
|
||||
threshold = (int) (sz * LOAD_FACTOR);
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor {
|
|||
|
||||
int h = hash(val);
|
||||
for (int slot = h & (vals.length-1); ;slot = (slot + ((h>>7)|1)) & (vals.length-1)) {
|
||||
int count = counts[slot];
|
||||
long count = counts[slot];
|
||||
if (count == 0) {
|
||||
counts[slot] = 1;
|
||||
vals[slot] = val;
|
||||
|
@ -111,14 +111,14 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor {
|
|||
|
||||
protected void rehash() {
|
||||
long[] oldVals = vals;
|
||||
int[] oldCounts = counts; // after retrieving the count, this array is reused as a mapping to new array
|
||||
long[] oldCounts = counts; // after retrieving the count, this array is reused as a mapping to new array
|
||||
int newCapacity = vals.length << 1;
|
||||
vals = new long[newCapacity];
|
||||
counts = new int[newCapacity];
|
||||
counts = new long[newCapacity];
|
||||
threshold = (int) (newCapacity * LOAD_FACTOR);
|
||||
|
||||
for (int i=0; i<oldVals.length; i++) {
|
||||
int count = oldCounts[i];
|
||||
long count = oldCounts[i];
|
||||
if (count == 0) {
|
||||
oldCounts[i] = -1;
|
||||
continue;
|
||||
|
@ -287,12 +287,12 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor {
|
|||
|
||||
countAcc = new CountSlotAcc(fcontext) {
|
||||
@Override
|
||||
public void incrementCount(int slot, int count) {
|
||||
public void incrementCount(int slot, long count) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount(int slot) {
|
||||
public long getCount(int slot) {
|
||||
return table.counts[slot];
|
||||
}
|
||||
|
||||
|
@ -313,7 +313,7 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor {
|
|||
|
||||
@Override
|
||||
public int compare(int slotA, int slotB) {
|
||||
return Integer.compare( table.counts[slotA], table.counts[slotB] );
|
||||
return Long.compare( table.counts[slotA], table.counts[slotB] );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -455,7 +455,7 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor {
|
|||
}
|
||||
|
||||
final int finalNumSlots = numSlots;
|
||||
final int[] mapping = table.oldToNewMapping;
|
||||
final long[] mapping = table.oldToNewMapping;
|
||||
|
||||
SlotAcc.Resizer resizer = new SlotAcc.Resizer() {
|
||||
@Override
|
||||
|
@ -466,7 +466,7 @@ class FacetFieldProcessorByHashDV extends FacetFieldProcessor {
|
|||
@Override
|
||||
public int getNewSlot(int oldSlot) {
|
||||
if (oldSlot < mapping.length) {
|
||||
return mapping[oldSlot];
|
||||
return (int) mapping[oldSlot];
|
||||
}
|
||||
if (oldSlot == oldAllBucketsSlot) {
|
||||
return allBucketsSlot;
|
||||
|
|
|
@ -290,19 +290,19 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
|
|||
return appliedFilters;
|
||||
}
|
||||
|
||||
protected void processStats(SimpleOrderedMap<Object> bucket, Query bucketQ, DocSet docs, int docCount) throws IOException {
|
||||
protected void processStats(SimpleOrderedMap<Object> bucket, Query bucketQ, DocSet docs, long docCount) throws IOException {
|
||||
if (docCount == 0 && !freq.processEmpty || freq.getFacetStats().size() == 0) {
|
||||
bucket.add("count", docCount);
|
||||
return;
|
||||
}
|
||||
createAccs(docCount, 1);
|
||||
int collected = collect(docs, 0, slotNum -> { return new SlotContext(bucketQ); });
|
||||
long collected = collect(docs, 0, slotNum -> { return new SlotContext(bucketQ); });
|
||||
countAcc.incrementCount(0, collected);
|
||||
assert collected == docCount;
|
||||
addStats(bucket, 0);
|
||||
}
|
||||
|
||||
protected void createAccs(int docCount, int slotCount) throws IOException {
|
||||
protected void createAccs(long docCount, int slotCount) throws IOException {
|
||||
accMap = new LinkedHashMap<>();
|
||||
|
||||
// allow a custom count acc to be used
|
||||
|
@ -332,8 +332,8 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
|
|||
}
|
||||
}
|
||||
|
||||
int collect(DocSet docs, int slot, IntFunction<SlotContext> slotContext) throws IOException {
|
||||
int count = 0;
|
||||
long collect(DocSet docs, int slot, IntFunction<SlotContext> slotContext) throws IOException {
|
||||
long count = 0;
|
||||
SolrIndexSearcher searcher = fcontext.searcher;
|
||||
|
||||
if (0 == docs.size()) {
|
||||
|
@ -392,7 +392,7 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
|
|||
}
|
||||
|
||||
void addStats(SimpleOrderedMap<Object> target, int slotNum) throws IOException {
|
||||
int count = countAcc.getCount(slotNum);
|
||||
long count = countAcc.getCount(slotNum);
|
||||
target.add("count", count);
|
||||
if (count > 0 || freq.processEmpty) {
|
||||
for (SlotAcc acc : accs) {
|
||||
|
@ -405,7 +405,7 @@ public abstract class FacetProcessor<FacetRequestT extends FacetRequest> {
|
|||
|
||||
boolean needDocSet = (skip==false && freq.getFacetStats().size() > 0) || freq.getSubFacets().size() > 0;
|
||||
|
||||
int count;
|
||||
long count;
|
||||
|
||||
if (result != null) {
|
||||
count = result.size();
|
||||
|
|
|
@ -578,7 +578,7 @@ class FacetRangeProcessor extends FacetProcessor<FacetRange> {
|
|||
DocSet intersection = fcontext.searcher.getDocSet(rangeQ, fcontext.base);
|
||||
filters[slot] = rangeQ;
|
||||
intersections[slot] = intersection; // save for later // TODO: only save if number of slots is small enough?
|
||||
int num = collect(intersection, slot, slotNum -> { return new SlotContext(rangeQ); });
|
||||
long num = collect(intersection, slot, slotNum -> { return new SlotContext(rangeQ); });
|
||||
countAcc.incrementCount(slot, num); // TODO: roll this into collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ public class HLLAgg extends StrAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
SchemaField sf = fcontext.qcontext.searcher().getSchema().getField(getArg());
|
||||
if (sf.multiValued() || sf.getType().multiValuedFieldCache()) {
|
||||
if (sf.getType().isPointField()) {
|
||||
|
|
|
@ -46,7 +46,7 @@ public class MinMaxAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
|
||||
SchemaField sf = null;
|
||||
|
|
|
@ -37,7 +37,7 @@ public class MissingAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
|
||||
if (vs instanceof FieldNameValueSource) {
|
||||
|
|
|
@ -49,7 +49,7 @@ public class PercentileAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
|
||||
if (vs instanceof FieldNameValueSource) {
|
||||
|
|
|
@ -122,7 +122,7 @@ public class RelatednessAgg extends AggValueSource {
|
|||
}
|
||||
|
||||
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
// TODO: Ideally this is where we should check fgQ/bgQ for 'null' and apply defaults...
|
||||
//
|
||||
// we want to walk up the fcontext and inherit the queries from any ancestor SKGAgg
|
||||
|
|
|
@ -578,17 +578,17 @@ abstract class CountSlotAcc extends SlotAcc {
|
|||
super(fcontext);
|
||||
}
|
||||
|
||||
public abstract void incrementCount(int slot, int count);
|
||||
public abstract void incrementCount(int slot, long count);
|
||||
|
||||
public abstract int getCount(int slot);
|
||||
public abstract long getCount(int slot);
|
||||
}
|
||||
|
||||
class CountSlotArrAcc extends CountSlotAcc {
|
||||
int[] result;
|
||||
long[] result;
|
||||
|
||||
public CountSlotArrAcc(FacetContext fcontext, int numSlots) {
|
||||
super(fcontext);
|
||||
result = new int[numSlots];
|
||||
result = new long[numSlots];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -600,7 +600,7 @@ class CountSlotArrAcc extends CountSlotAcc {
|
|||
|
||||
@Override
|
||||
public int compare(int slotA, int slotB) {
|
||||
return Integer.compare(result[slotA], result[slotB]);
|
||||
return Long.compare(result[slotA], result[slotB]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -608,16 +608,18 @@ class CountSlotArrAcc extends CountSlotAcc {
|
|||
return result[slotNum];
|
||||
}
|
||||
|
||||
public void incrementCount(int slot, int count) {
|
||||
@Override
|
||||
public void incrementCount(int slot, long count) {
|
||||
result[slot] += count;
|
||||
}
|
||||
|
||||
public int getCount(int slot) {
|
||||
@Override
|
||||
public long getCount(int slot) {
|
||||
return result[slot];
|
||||
}
|
||||
|
||||
// internal and expert
|
||||
int[] getCountArray() {
|
||||
long[] getCountArray() {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -642,6 +644,7 @@ class SortSlotAcc extends SlotAcc {
|
|||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(int slotA, int slotB) {
|
||||
return slotA - slotB;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public class StddevAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
|
||||
if (vs instanceof FieldNameValueSource) {
|
||||
|
|
|
@ -34,7 +34,7 @@ public class SumAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
|
||||
if (vs instanceof FieldNameValueSource) {
|
||||
|
|
|
@ -33,7 +33,7 @@ public class SumsqAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
|
||||
if (vs instanceof FieldNameValueSource) {
|
||||
|
|
|
@ -390,7 +390,7 @@ public class UnInvertedField extends DocTermOrds {
|
|||
if (doNegative) {
|
||||
for (int i=0; i<numTermsInField; i++) {
|
||||
// counts[i] = maxTermCounts[i] - counts[i];
|
||||
counts.incrementCount(i, maxTermCounts[i] - counts.getCount(i)*2);
|
||||
counts.incrementCount(i, maxTermCounts[i] - (int) counts.getCount(i)*2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public class UniqueAgg extends StrAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
SchemaField sf = fcontext.qcontext.searcher().getSchema().getField(getArg());
|
||||
if (sf.multiValued() || sf.getType().multiValuedFieldCache()) {
|
||||
if (sf.getType().isPointField()) {
|
||||
|
|
|
@ -79,7 +79,7 @@ public abstract class UniqueBlockAgg extends UniqueAgg {
|
|||
}
|
||||
|
||||
@Override
|
||||
public abstract SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException ;
|
||||
public abstract SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException ;
|
||||
|
||||
@Override
|
||||
public FacetMerger createFacetMerger(Object prototype) {
|
||||
|
|
|
@ -27,7 +27,7 @@ public class UniqueBlockFieldAgg extends UniqueBlockAgg {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
final String fieldName = getArg();
|
||||
SchemaField sf = fcontext.qcontext.searcher().getSchema().getField(fieldName);
|
||||
if (sf.multiValued() || sf.getType().multiValuedFieldCache()) {
|
||||
|
|
|
@ -65,7 +65,7 @@ public class UniqueBlockQueryAgg extends UniqueBlockAgg {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
return new UniqueBlockQuerySlotAcc(fcontext, query, numSlots);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class VarianceAgg extends SimpleAggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
ValueSource vs = getArg();
|
||||
|
||||
if (vs instanceof FieldNameValueSource) {
|
||||
|
|
|
@ -518,16 +518,16 @@ public class CurrencyFieldTypeTest extends SolrTestCaseJ4 {
|
|||
"{ xxx : { type:range, field:" + fieldName + ", " +
|
||||
" start:'4.00"+suffix+"', gap:'1.00"+suffix+"', end:'11.00"+suffix+"', other:all } }")
|
||||
,"count(//lst[@name='xxx']/arr[@name='buckets']/lst)=7"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='4.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='5.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='6.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='7.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='8.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='9.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='10.00,USD']]"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/int[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/int[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/int[@name='count'][.='3']"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='4.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='5.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='6.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='7.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='8.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='9.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='10.00,USD']]"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/long[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/long[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/long[@name='count'][.='3']"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -552,13 +552,13 @@ public class CurrencyFieldTypeTest extends SolrTestCaseJ4 {
|
|||
"{ xxx : { type:range, mincount:1, field:" + fieldName +
|
||||
", start:'0.00,USD', gap:'1.00,USD', end:'11.00,USD', other:all } }")
|
||||
,"count(//lst[@name='xxx']/arr[@name='buckets']/lst)=4"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='3.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='4.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='7.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='10.00,USD']]"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/int[@name='count'][.='0']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/int[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/int[@name='count'][.='4']"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='3.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='4.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='7.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='10.00,USD']]"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/long[@name='count'][.='0']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/long[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/long[@name='count'][.='4']"
|
||||
);
|
||||
|
||||
// NOTE: because of asymetric EUR exchange rate, these buckets are diff then the similar looking USD based request above
|
||||
|
@ -587,16 +587,16 @@ public class CurrencyFieldTypeTest extends SolrTestCaseJ4 {
|
|||
req("fl", "*,score", "q", "*:*", "rows", "0", "json.facet",
|
||||
"{ xxx : { type:range, field:" + fieldName + ", start:'8.00,EUR', gap:'2.00,EUR', end:'22.00,EUR', other:all } }")
|
||||
,"count(//lst[@name='xxx']/arr[@name='buckets']/lst)=7"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='8.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='10.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='12.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='14.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='16.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='18.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='20.00,EUR']]"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/int[@name='count'][.='2']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/int[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/int[@name='count'][.='2']"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='8.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='10.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='12.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='14.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='16.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='18.00,EUR']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='20.00,EUR']]"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/long[@name='count'][.='2']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/long[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/long[@name='count'][.='2']"
|
||||
);
|
||||
|
||||
|
||||
|
@ -627,16 +627,16 @@ public class CurrencyFieldTypeTest extends SolrTestCaseJ4 {
|
|||
req("fl", "*,score", "q", "*:*", "rows", "0", "json.facet",
|
||||
"{ xxx : { type:range, field:" + fieldName + ", start:'2.00,GBP', gap:'0.50,GBP', end:'5.50,GBP', other:all } }")
|
||||
,"count(//lst[@name='xxx']/arr[@name='buckets']/lst)=7"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='2.00,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='2.50,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='3.00,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='3.50,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='4.00,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='4.50,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='5.00,GBP']]"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/int[@name='count'][.='0']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/int[@name='count'][.='2']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/int[@name='count'][.='3']"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='2.00,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='2.50,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='3.00,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='3.50,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='4.00,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='4.50,GBP']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='5.00,GBP']]"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/long[@name='count'][.='0']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/long[@name='count'][.='2']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/long[@name='count'][.='3']"
|
||||
);
|
||||
|
||||
assertQ("Ensure that we can set a gap in a currency other than the start and end currencies (facet.range)",
|
||||
|
@ -663,17 +663,17 @@ public class CurrencyFieldTypeTest extends SolrTestCaseJ4 {
|
|||
req("fl", "*,score", "q", "*:*", "rows", "0", "json.facet",
|
||||
"{ xxx : { type:range, field:" + fieldName + ", start:'4.00,USD', gap:'0.50,GBP', end:'11.00,USD', other:all } }")
|
||||
,"count(//lst[@name='xxx']/arr[@name='buckets']/lst)=7"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='4.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='5.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='6.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='7.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='8.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='0']][str[@name='val'][.='9.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[int[@name='count'][.='1']][str[@name='val'][.='10.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='4.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='5.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='6.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='7.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='8.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='0']][str[@name='val'][.='9.00,USD']]"
|
||||
,"//lst[@name='xxx']/arr[@name='buckets']/lst[long[@name='count'][.='1']][str[@name='val'][.='10.00,USD']]"
|
||||
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/int[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/int[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/int[@name='count'][.='3']"
|
||||
,"//lst[@name='xxx']/lst[@name='before' ]/long[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='after' ]/long[@name='count'][.='1']"
|
||||
,"//lst[@name='xxx']/lst[@name='between']/long[@name='count'][.='3']"
|
||||
);
|
||||
|
||||
for (SolrParams facet : Arrays.asList(params("facet", "true",
|
||||
|
|
|
@ -193,9 +193,9 @@ public class TestSortableTextField extends SolrTestCaseJ4 {
|
|||
assertQ(req("q", search + ":cow", "rows", "0",
|
||||
"json.facet", "{x:{ type: terms, field:'" + facet + "', mincount:0 }}")
|
||||
, "//*[@numFound='3']"
|
||||
, jpre + "lst[str[@name='val'][.='how now brown cow ?']][int[@name='count'][.=2]]"
|
||||
, jpre + "lst[str[@name='val'][.='holy cow !']][int[@name='count'][.=1]]"
|
||||
, jpre + "lst[str[@name='val'][.='dog and cat']][int[@name='count'][.=0]]"
|
||||
, jpre + "lst[str[@name='val'][.='how now brown cow ?']][long[@name='count'][.=2]]"
|
||||
, jpre + "lst[str[@name='val'][.='holy cow !']][long[@name='count'][.=1]]"
|
||||
, jpre + "lst[str[@name='val'][.='dog and cat']][long[@name='count'][.=0]]"
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
private static String FIELD = null; // randomized
|
||||
|
||||
private static final List<String> STR_VALS = Arrays.asList("x0", "x1", "x2");
|
||||
// NOTE: in our test conversions EUR uses an asynetric echange rate
|
||||
// NOTE: in our test conversions EUR uses an asynetric exchange rate
|
||||
// these are the equivalent values relative to: USD EUR GBP
|
||||
private static final List<String> VALUES = Arrays.asList("10.00,USD", // 10.00,USD 25.00,EUR 5.00,GBP
|
||||
"15.00,EUR", // 7.50,USD 15.00,EUR 7.50,GBP
|
||||
|
@ -176,9 +176,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
|
||||
final NamedList<Object> foo = ((NamedList<NamedList<Object>>)rsp.getResponse().get("facets")).get("foo");
|
||||
|
||||
assertEqualsHACK("before", 3L, ((NamedList)foo.get("before")).get("count"));
|
||||
assertEqualsHACK("after", 3L, ((NamedList)foo.get("after")).get("count"));
|
||||
assertEqualsHACK("between", 9L, ((NamedList)foo.get("between")).get("count"));
|
||||
assertEquals("before", 3L, ((NamedList)foo.get("before")).get("count"));
|
||||
assertEquals("after", 3L, ((NamedList)foo.get("after")).get("count"));
|
||||
assertEquals("between", 9L, ((NamedList)foo.get("between")).get("count"));
|
||||
|
||||
final List<NamedList> buckets = (List<NamedList>) foo.get("buckets");
|
||||
|
||||
|
@ -187,14 +187,14 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
for (int i = 0; i < 3; i++) {
|
||||
NamedList bucket = buckets.get(i);
|
||||
assertEquals((4 + (3 * i)) + ".00,USD", bucket.get("val"));
|
||||
assertEqualsHACK("bucket #" + i, 3L, bucket.get("count"));
|
||||
assertEquals("bucket #" + i, 3L, bucket.get("count"));
|
||||
}
|
||||
} else {
|
||||
assertEquals(7, buckets.size());
|
||||
for (int i = 0; i < 7; i++) {
|
||||
NamedList bucket = buckets.get(i);
|
||||
assertEquals((4 + i) + ".00,USD", bucket.get("val"));
|
||||
assertEqualsHACK("bucket #" + i, (i == 0 || i == 3 || i == 6) ? 3L : 0L, bucket.get("count"));
|
||||
assertEquals("bucket #" + i, (i == 0 || i == 3 || i == 6) ? 3L : 0L, bucket.get("count"));
|
||||
}
|
||||
}
|
||||
} catch (AssertionError|RuntimeException ae) {
|
||||
|
@ -268,9 +268,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
|
||||
final NamedList<Object> foo = ((NamedList<NamedList<Object>>)rsp.getResponse().get("facets")).get("foo");
|
||||
|
||||
assertEqualsHACK("before", 6L, ((NamedList)foo.get("before")).get("count"));
|
||||
assertEqualsHACK("after", 3L, ((NamedList)foo.get("after")).get("count"));
|
||||
assertEqualsHACK("between", 6L, ((NamedList)foo.get("between")).get("count"));
|
||||
assertEquals("before", 6L, ((NamedList)foo.get("before")).get("count"));
|
||||
assertEquals("after", 3L, ((NamedList)foo.get("after")).get("count"));
|
||||
assertEquals("between", 6L, ((NamedList)foo.get("between")).get("count"));
|
||||
|
||||
final List<NamedList> buckets = (List<NamedList>) foo.get("buckets");
|
||||
|
||||
|
@ -279,14 +279,14 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
for (int i = 0; i < 2; i++) {
|
||||
NamedList bucket = buckets.get(i);
|
||||
assertEquals((12 + (i * 2)) + ".00,EUR", bucket.get("val"));
|
||||
assertEqualsHACK("bucket #" + i, 3L, bucket.get("count"));
|
||||
assertEquals("bucket #" + i, 3L, bucket.get("count"));
|
||||
}
|
||||
} else {
|
||||
assertEquals(7, buckets.size());
|
||||
for (int i = 0; i < 7; i++) {
|
||||
NamedList bucket = buckets.get(i);
|
||||
assertEquals((8 + (i * 2)) + ".00,EUR", bucket.get("val"));
|
||||
assertEqualsHACK("bucket #" + i, (i == 2 || i == 3) ? 3L : 0L, bucket.get("count"));
|
||||
assertEquals("bucket #" + i, (i == 2 || i == 3) ? 3L : 0L, bucket.get("count"));
|
||||
}
|
||||
}
|
||||
} catch (AssertionError|RuntimeException ae) {
|
||||
|
@ -365,9 +365,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
|
||||
// sanity check our high level expectations...
|
||||
assertEquals("bar num buckets", 2, bar_buckets.size());
|
||||
assertEqualsHACK("before count", 0L, before.get("count"));
|
||||
assertEqualsHACK("between count", 8L, between.get("count"));
|
||||
assertEqualsHACK("after count", 2L, after.get("count"));
|
||||
assertEquals("before count", 0L, before.get("count"));
|
||||
assertEquals("between count", 8L, between.get("count"));
|
||||
assertEquals("after count", 2L, after.get("count"));
|
||||
|
||||
// drill into the various buckets...
|
||||
|
||||
|
@ -378,15 +378,15 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
for (int i = 0; i < 2; i++) {
|
||||
final NamedList<Object> bucket = bar_buckets.get(i);
|
||||
assertEquals((i * 10) + ".00,EUR", bucket.get("val"));
|
||||
assertEqualsHACK("bucket #" + i, 4L, bucket.get("count"));
|
||||
assertEquals("bucket #" + i, 4L, bucket.get("count"));
|
||||
final List<NamedList<Object>> foo_buckets = ((NamedList<List<NamedList<Object>>>)bucket.get("foo")).get("buckets");
|
||||
assertEquals("bucket #" + i + " foo num buckets", 2, foo_buckets.size());
|
||||
assertEquals("bucket #" + i + " foo top term", (0==i ? "x2" : "x0"), foo_buckets.get(0).get("val"));
|
||||
assertEqualsHACK("bucket #" + i + " foo top count", 2, foo_buckets.get(0).get("count"));
|
||||
assertEquals("bucket #" + i + " foo top count", 2L, foo_buckets.get(0).get("count"));
|
||||
// NOTE: we can't make any assertions about the 2nd val..
|
||||
// our limit + randomized sharding could result in either remaining term being picked.
|
||||
// but for eiter term, the count should be exactly the same...
|
||||
assertEqualsHACK("bucket #" + i + " foo 2nd count", 1, foo_buckets.get(1).get("count"));
|
||||
// but for either term, the count should be exactly the same...
|
||||
assertEquals("bucket #" + i + " foo 2nd count", 1L, foo_buckets.get(1).get("count"));
|
||||
}
|
||||
|
||||
{ // between...
|
||||
|
@ -394,9 +394,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
assertEquals("between num buckets", 2, buckets.size());
|
||||
// the counts should both be 3, and the term order should break the tie...
|
||||
assertEquals("between bucket top", "x0", buckets.get(0).get("val"));
|
||||
assertEqualsHACK("between bucket top count", 3L, buckets.get(0).get("count"));
|
||||
assertEquals("between bucket top count", 3L, buckets.get(0).get("count"));
|
||||
assertEquals("between bucket 2nd", "x2", buckets.get(1).get("val"));
|
||||
assertEqualsHACK("between bucket 2nd count", 3L, buckets.get(1).get("count"));
|
||||
assertEquals("between bucket 2nd count", 3L, buckets.get(1).get("count"));
|
||||
}
|
||||
|
||||
{ // after...
|
||||
|
@ -404,9 +404,9 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
assertEquals("after num buckets", 2, buckets.size());
|
||||
// the counts should both be 1, and the term order should break the tie...
|
||||
assertEquals("after bucket top", "x1", buckets.get(0).get("val"));
|
||||
assertEqualsHACK("after bucket top count", 1L, buckets.get(0).get("count"));
|
||||
assertEquals("after bucket top count", 1L, buckets.get(0).get("count"));
|
||||
assertEquals("after bucket 2nd", "x2", buckets.get(1).get("val"));
|
||||
assertEqualsHACK("after bucket 2nd count", 1L, buckets.get(1).get("count"));
|
||||
assertEquals("after bucket 2nd count", 1L, buckets.get(1).get("count"));
|
||||
}
|
||||
|
||||
} catch (AssertionError|RuntimeException ae) {
|
||||
|
@ -449,15 +449,15 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
final List<NamedList<Object>> foo_buckets = (List<NamedList<Object>>) foo.get("buckets");
|
||||
assertEquals(1, foo_buckets.size());
|
||||
assertEquals("x2", foo_buckets.get(0).get("val"));
|
||||
assertEqualsHACK("foo bucket count", 5L, foo_buckets.get(0).get("count"));
|
||||
assertEquals("foo bucket count", 5L, foo_buckets.get(0).get("count"));
|
||||
|
||||
final NamedList<Object> bar = (NamedList<Object>)foo_buckets.get(0).get("bar");
|
||||
|
||||
// these are the 'x2' specific counts, based on our fq...
|
||||
|
||||
assertEqualsHACK("before", 2L, ((NamedList)bar.get("before")).get("count"));
|
||||
assertEqualsHACK("after", 1L, ((NamedList)bar.get("after")).get("count"));
|
||||
assertEqualsHACK("between", 2L, ((NamedList)bar.get("between")).get("count"));
|
||||
assertEquals("before", 2L, ((NamedList)bar.get("before")).get("count"));
|
||||
assertEquals("after", 1L, ((NamedList)bar.get("after")).get("count"));
|
||||
assertEquals("between", 2L, ((NamedList)bar.get("between")).get("count"));
|
||||
|
||||
final List<NamedList> buckets = (List<NamedList>) bar.get("buckets");
|
||||
assertEquals(7, buckets.size());
|
||||
|
@ -465,7 +465,7 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
NamedList bucket = buckets.get(i);
|
||||
assertEquals((8 + (i * 2)) + ".00,EUR", bucket.get("val"));
|
||||
// 12,EUR & 15,EUR are the 2 values that align with x2 docs
|
||||
assertEqualsHACK("bucket #" + i, (i == 2 || i == 3) ? 1L : 0L, bucket.get("count"));
|
||||
assertEquals("bucket #" + i, (i == 2 || i == 3) ? 1L : 0L, bucket.get("count"));
|
||||
}
|
||||
} catch (AssertionError|RuntimeException ae) {
|
||||
throw new AssertionError(solrQuery.toString() + " -> " + rsp.toString() + " ===> " + ae.getMessage(), ae);
|
||||
|
@ -473,14 +473,4 @@ public class CurrencyRangeFacetCloudTest extends SolrCloudTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HACK to work around SOLR-11775.
|
||||
* Asserts that the 'actual' argument is a (non-null) Number, then compares it's 'longValue' to the 'expected' argument
|
||||
*/
|
||||
private static void assertEqualsHACK(String msg, long expected, Object actual) {
|
||||
assertNotNull(msg, actual);
|
||||
assertTrue(msg + " ... NOT A NUMBER: " + actual.getClass(), Number.class.isInstance(actual));
|
||||
assertEquals(msg, expected, ((Number)actual).longValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ class DebugAgg extends AggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) throws IOException {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) throws IOException {
|
||||
return new Acc(fcontext, numDocs, numSlots, inner.createSlotAcc(fcontext, numDocs, numSlots));
|
||||
}
|
||||
|
||||
|
@ -91,10 +91,10 @@ class DebugAgg extends AggValueSource {
|
|||
public static Acc last;
|
||||
|
||||
public SlotAcc sub;
|
||||
public int numDocs;
|
||||
public long numDocs;
|
||||
public int numSlots;
|
||||
|
||||
public Acc(FacetContext fcontext, int numDocs, int numSlots, SlotAcc sub) {
|
||||
public Acc(FacetContext fcontext, long numDocs, int numSlots, SlotAcc sub) {
|
||||
super(fcontext);
|
||||
this.last = this;
|
||||
this.numDocs = numDocs;
|
||||
|
@ -173,7 +173,7 @@ class DebugAgg extends AggValueSource {
|
|||
}
|
||||
|
||||
@Override
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, int numDocs, int numSlots) {
|
||||
public SlotAcc createSlotAcc(FacetContext fcontext, long numDocs, int numSlots) {
|
||||
return new NumShardsAcc(fcontext, numDocs, numSlots);
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ class DebugAgg extends AggValueSource {
|
|||
}
|
||||
|
||||
public static class NumShardsAcc extends SlotAcc {
|
||||
public NumShardsAcc(FacetContext fcontext, int numDocs, int numSlots) {
|
||||
public NumShardsAcc(FacetContext fcontext, long numDocs, int numSlots) {
|
||||
super(fcontext);
|
||||
}
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ public class DistributedFacetSimpleRefinementLongTailTest extends BaseDistribute
|
|||
for (int j = 0; j < 5; j++) {
|
||||
NamedList bucket = shardFooBuckets[i].get(j);
|
||||
assertEquals(bucket.toString(), "aaa"+j, bucket.get("val"));
|
||||
assertEquals(bucket.toString(), 100, bucket.get("count"));
|
||||
assertEquals(bucket.toString(), 100L, bucket.get("count"));
|
||||
}
|
||||
}
|
||||
// top 6-10 same on shard0 & shard1
|
||||
|
@ -155,19 +155,19 @@ public class DistributedFacetSimpleRefinementLongTailTest extends BaseDistribute
|
|||
for (int j = 5; j < 10; j++) {
|
||||
NamedList bucket = shardFooBuckets[i].get(j);
|
||||
assertTrue(bucket.toString(), bucket.get("val").toString().startsWith("bbb"));
|
||||
assertEquals(bucket.toString(), 50, bucket.get("count"));
|
||||
assertEquals(bucket.toString(), 50L, bucket.get("count"));
|
||||
}
|
||||
}
|
||||
|
||||
// 6-10 on shard2
|
||||
assertEquals("junkA", shardFooBuckets[2].get(5).get("val"));
|
||||
assertEquals(50, shardFooBuckets[2].get(5).get("count"));
|
||||
assertEquals(50L, shardFooBuckets[2].get(5).get("count"));
|
||||
assertEquals("tail", shardFooBuckets[2].get(6).get("val"));
|
||||
assertEquals(45, shardFooBuckets[2].get(6).get("count"));
|
||||
assertEquals(45L, shardFooBuckets[2].get(6).get("count"));
|
||||
for (int j = 7; j < 10; j++) {
|
||||
NamedList bucket = shardFooBuckets[2].get(j);
|
||||
assertTrue(bucket.toString(), bucket.get("val").toString().startsWith("ZZZ"));
|
||||
assertEquals(bucket.toString(), 1, bucket.get("count"));
|
||||
assertEquals(bucket.toString(), 1L, bucket.get("count"));
|
||||
}
|
||||
|
||||
// check 'bar' sub buckets on "tail" from shard2
|
||||
|
@ -176,11 +176,11 @@ public class DistributedFacetSimpleRefinementLongTailTest extends BaseDistribute
|
|||
for (int j = 0; j < 5; j++) {
|
||||
NamedList bucket = bar_buckets.get(j);
|
||||
assertTrue(bucket.toString(), bucket.get("val").toString().startsWith("junkB"));
|
||||
assertEquals(bucket.toString(), 8, bucket.get("count"));
|
||||
assertEquals(bucket.toString(), 8L, bucket.get("count"));
|
||||
}
|
||||
NamedList bucket = bar_buckets.get(5);
|
||||
assertEquals("tailB", bucket.get("val"));
|
||||
assertEquals(5, bucket.get("count"));
|
||||
assertEquals(5L, bucket.get("count"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -741,7 +741,7 @@ public class RangeFacetCloudTest extends SolrCloudTestCase {
|
|||
toMerge.add(TERM_MODEL[i]);
|
||||
}
|
||||
|
||||
assertEqualsHACK("count", expectedCount, bucket.get("count"));
|
||||
assertEquals("count", expectedCount, bucket.get("count"));
|
||||
|
||||
// merge the maps of our range values by summing the (int) values on key collisions
|
||||
final Map<String,Long> expectedTermCounts = toMerge.stream()
|
||||
|
@ -766,7 +766,7 @@ public class RangeFacetCloudTest extends SolrCloudTestCase {
|
|||
assertNotNull("subfacet bucket with null term: " + subBucket, term);
|
||||
final Long expectedTermCount = expectedTermCounts.get(term.toString());
|
||||
assertNotNull("unexpected subfacet bucket: " + subBucket, expectedTermCount);
|
||||
assertEqualsHACK("subfacet count for term: " + term, expectedTermCount, subBucket.get("count"));
|
||||
assertEquals("subfacet count for term: " + term, expectedTermCount, subBucket.get("count"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -910,14 +910,4 @@ public class RangeFacetCloudTest extends SolrCloudTestCase {
|
|||
return ", other:" + val;
|
||||
}
|
||||
|
||||
/**
|
||||
* HACK to work around SOLR-11775.
|
||||
* Asserts that the 'actual' argument is a (non-null) Number, then compares it's 'longValue' to the 'expected' argument
|
||||
*/
|
||||
private static void assertEqualsHACK(String msg, long expected, Object actual) {
|
||||
assertNotNull(msg, actual);
|
||||
assertTrue(msg + " ... NOT A NUMBER: " + actual.getClass(), Number.class.isInstance(actual));
|
||||
assertEquals(msg, expected, ((Number)actual).longValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3283,6 +3283,64 @@ public class TestJsonFacets extends SolrTestCaseHS {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFacetValueTypes() throws Exception {
|
||||
doFacetValueTypeValidation(Client.localClient());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFacetValueTypesDistrib() throws Exception {
|
||||
initServers();
|
||||
Client client = servers.getClient(random().nextInt());
|
||||
client.queryDefaults().set( "shards", servers.getShards(), "debugQuery", Boolean.toString(random().nextBoolean()) );
|
||||
doFacetValueTypeValidation(client);
|
||||
}
|
||||
|
||||
private void doFacetValueTypeValidation(Client client) throws Exception {
|
||||
indexSimple(client);
|
||||
|
||||
client.testXQ(params("q", "*:*", "rows", "0",
|
||||
"json.facet", "{cat_s:{type:terms,field:cat_s,mincount:0,missing:true,allBuckets:true,numBuckets:true,limit:1}}"),
|
||||
"/response/lst[@name='facets']/long[@name='count'][.=6]", // count
|
||||
"/response/lst[@name='facets']/lst[@name='cat_s']/long[@name='numBuckets'][.=2]", // total no of buckets
|
||||
"*[count(/response/lst[@name='facets']/lst[@name='cat_s']/arr[@name='buckets']/lst)=1]", // no of entries
|
||||
"/response/lst[@name='facets']/lst[@name='cat_s']/lst[@name='allBuckets']/long[@name='count'][.=5]", // allBuckets
|
||||
"/response/lst[@name='facets']/lst[@name='cat_s']/lst[@name='missing']/long[@name='count'][.=1]", // missing
|
||||
"/response/lst[@name='facets']/lst[@name='cat_s']/arr[@name='buckets']/lst[1]/str[@name='val'][.='B']", // facet value
|
||||
"/response/lst[@name='facets']/lst[@name='cat_s']/arr[@name='buckets']/lst[1]/long[@name='count'][.='3']" // facet count
|
||||
);
|
||||
|
||||
// aggregations types for string
|
||||
client.testXQ(params("q", "*:*", "rows", "0",
|
||||
"json.facet", "{unique:'unique(cat_s)',hll:'hll(cat_s)',vals:'countvals(cat_s)',missing:'missing(cat_s)'}"),
|
||||
"/response/lst[@name='facets']/long[@name='count'][.=6]", // count
|
||||
"/response/lst[@name='facets']/long[@name='unique'][.=2]", // unique
|
||||
"/response/lst[@name='facets']/long[@name='hll'][.=2]", // hll
|
||||
"/response/lst[@name='facets']/long[@name='vals'][.=5]", // values
|
||||
"/response/lst[@name='facets']/long[@name='missing'][.=1]" // missing
|
||||
);
|
||||
|
||||
// aggregations types for number
|
||||
client.testXQ(params("q", "*:*", "rows", "0",
|
||||
"json.facet", "{unique:'unique(num_i)',hll:'hll(num_i)',vals:'countvals(num_i)',missing:'missing(num_i)'}"),
|
||||
"/response/lst[@name='facets']/long[@name='count'][.=6]", // count
|
||||
"/response/lst[@name='facets']/long[@name='unique'][.=4]", // unique
|
||||
"/response/lst[@name='facets']/long[@name='hll'][.=4]", // hll
|
||||
"/response/lst[@name='facets']/long[@name='vals'][.=5]", // values
|
||||
"/response/lst[@name='facets']/long[@name='missing'][.=1]" // missing
|
||||
);
|
||||
|
||||
// aggregations types for multi-valued number
|
||||
client.testXQ(params("q", "*:*", "rows", "0",
|
||||
"json.facet", "{unique:'unique(num_is)',hll:'hll(num_is)',vals:'countvals(num_is)',missing:'missing(num_is)'}"),
|
||||
"/response/lst[@name='facets']/long[@name='count'][.=6]", // count
|
||||
"/response/lst[@name='facets']/long[@name='unique'][.=7]", // unique
|
||||
"/response/lst[@name='facets']/long[@name='hll'][.=7]", // hll
|
||||
"/response/lst[@name='facets']/long[@name='vals'][.=9]", // values
|
||||
"/response/lst[@name='facets']/long[@name='missing'][.=1]" // missing
|
||||
);
|
||||
}
|
||||
|
||||
public void XtestPercentiles() {
|
||||
AVLTreeDigest catA = new AVLTreeDigest(100);
|
||||
catA.add(4);
|
||||
|
|
|
@ -394,4 +394,42 @@ public class TestJsonRangeFacets extends SolrTestCaseHS {
|
|||
"facets=={count:6, price:{buckets:[{val:\"[*,*)\",count:5}]}}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFacetValueTypes() throws Exception {
|
||||
doFacetValueTypeValidation(Client.localClient());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFacetValueTypeDistrib() throws Exception {
|
||||
initServers();
|
||||
Client client = servers.getClient(random().nextInt());
|
||||
client.queryDefaults().set( "shards", servers.getShards(), "debugQuery", Boolean.toString(random().nextBoolean()) );
|
||||
doFacetValueTypeValidation(client);
|
||||
}
|
||||
|
||||
private void doFacetValueTypeValidation(Client client) throws Exception {
|
||||
indexSimple(client);
|
||||
|
||||
// range faceting with start, end, and gap
|
||||
client.testXQ(params("q", "*:*", "rows", "0",
|
||||
"json.facet", "{num:{type: range, field:num_i,start:0,gap:2,end:10,mincount:1,other:all}}"),
|
||||
"/response/lst[@name='facets']/long[@name='count'][.=6]", // count
|
||||
"/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst[1]/int[@name='val'][.=2]", // value
|
||||
"/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst[1]/long[@name='count'][.=2]", // count
|
||||
"*[count(/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst)=2]", // no of entries
|
||||
"/response/lst[@name='facets']/lst[@name='num']/lst[@name='before']/long[@name='count'][.=2]", // before
|
||||
"/response/lst[@name='facets']/lst[@name='num']/lst[@name='after']/long[@name='count'][.=0]", // after
|
||||
"/response/lst[@name='facets']/lst[@name='num']/lst[@name='between']/long[@name='count'][.=3]" // between
|
||||
);
|
||||
|
||||
// range faceting with ranges specified
|
||||
client.testXQ(params("q", "*:*", "rows", "0",
|
||||
"json.facet", "{num:{type: range, field:num_i,ranges:[{from:0, to:4},{from:-4,to:2}],mincount:1}}"),
|
||||
"/response/lst[@name='facets']/long[@name='count'][.=6]", // count
|
||||
"/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst[1]/str[@name='val'][.='[0,4)']", // value
|
||||
"/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst[1]/long[@name='count'][.=2]", // count
|
||||
"*[count(/response/lst[@name='facets']/lst[@name='num']/arr[@name='buckets']/lst)=1]" // no of entries
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -104,6 +104,8 @@ _(raw; not yet edited)_
|
|||
* SOLR-12720: To change the auto add replica wait period modify the `waitFor` attribute of the `.auto_add_replicas` trigger.
|
||||
(marcussorealheis, shalin)
|
||||
|
||||
* SOLR-11775: Return long value for facet count in Json Facet module irrespective of number of shards (hossman, Munendra S N)
|
||||
|
||||
=== Upgrade Prerequisites in Solr 9
|
||||
|
||||
=== Rolling Upgrades with Solr 9
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.apache.solr;
|
||||
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
@ -45,6 +46,7 @@ import org.apache.solr.client.solrj.impl.NoOpResponseParser;
|
|||
import org.apache.solr.client.solrj.request.QueryRequest;
|
||||
import org.apache.solr.client.solrj.request.UpdateRequest;
|
||||
import org.apache.solr.client.solrj.response.UpdateResponse;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
|
@ -54,6 +56,7 @@ import org.apache.solr.request.SolrQueryRequest;
|
|||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.SchemaField;
|
||||
import org.apache.solr.servlet.DirectSolrConnection;
|
||||
import org.apache.solr.util.TestHarness;
|
||||
import org.noggit.JSONUtil;
|
||||
import org.noggit.ObjectBuilder;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -145,6 +148,31 @@ public class SolrTestCaseHS extends SolrTestCaseJ4 {
|
|||
matchJSON(resp, tests);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass "null" for the client to query to the local server.
|
||||
* Fetches response in xml format and matches with the given set of xpaths
|
||||
*/
|
||||
public static void assertQ(SolrClient client, SolrParams args, String... tests) throws Exception {
|
||||
String resp;
|
||||
resp = getQueryResponse(client, "xml", args);
|
||||
try {
|
||||
String results = TestHarness.validateXPath(resp, tests);
|
||||
if (null != results) {
|
||||
String msg = "REQUEST FAILED: xpath=" + results
|
||||
+ "\n\txml response was: " + resp
|
||||
+ "\n\tparams were:" + args.toQueryString();
|
||||
|
||||
log.error(msg);
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
} catch (XPathExpressionException e1) {
|
||||
throw new RuntimeException("XPath is invalid", e1);
|
||||
} catch (Exception e2) {
|
||||
SolrException.log(log,"REQUEST FAILED for params: " + args.toQueryString(), e2);
|
||||
throw new RuntimeException("Exception during query", e2);
|
||||
}
|
||||
}
|
||||
|
||||
public static void matchJSON(String response, String... tests) throws Exception {
|
||||
boolean failed = false;
|
||||
|
||||
|
@ -256,6 +284,10 @@ public class SolrTestCaseHS extends SolrTestCaseJ4 {
|
|||
public void assertJQ(SolrClient client, SolrParams args, String... tests) throws Exception {
|
||||
SolrTestCaseHS.assertJQ(client, args, tests);
|
||||
}
|
||||
|
||||
public void assertQ(SolrClient client, SolrParams args, String... tests) throws Exception {
|
||||
SolrTestCaseHS.assertQ(client, args, tests);
|
||||
}
|
||||
}
|
||||
|
||||
public static Client localClient = new Client(null, 1);
|
||||
|
@ -299,6 +331,19 @@ public class SolrTestCaseHS extends SolrTestCaseJ4 {
|
|||
tester.assertJQ(client, args, tests);
|
||||
}
|
||||
|
||||
/**
|
||||
* tests are validated against xml response
|
||||
*/
|
||||
public void testXQ(SolrParams args, String... tests) throws Exception {
|
||||
if (queryDefaults != null) {
|
||||
ModifiableSolrParams newParams = params(queryDefaults);
|
||||
newParams.add(args);
|
||||
args = newParams;
|
||||
}
|
||||
SolrClient client = provider==null ? null : provider.client(null, args);
|
||||
tester.assertQ(client, args, tests);
|
||||
}
|
||||
|
||||
public Long add(SolrInputDocument sdoc, ModifiableSolrParams params) throws Exception {
|
||||
SolrClient client = provider==null ? null : provider.client(sdoc, params);
|
||||
return SolrTestCaseHS.add(client, sdoc, params);
|
||||
|
|
Loading…
Reference in New Issue