Range Facet: Fix wrong total computation with multi valued fields by introducing total_count, add min/max stats, closes #832.
This commit is contained in:
parent
90a339ad5e
commit
79939222e4
|
@ -112,7 +112,10 @@ public class InternalRangeFacet implements RangeFacet, InternalFacet {
|
|||
entry.toAsString = in.readUTF();
|
||||
}
|
||||
entry.count = in.readVLong();
|
||||
entry.totalCount = in.readVLong();
|
||||
entry.total = in.readDouble();
|
||||
entry.min = in.readDouble();
|
||||
entry.max = in.readDouble();
|
||||
entries[i] = entry;
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +139,10 @@ public class InternalRangeFacet implements RangeFacet, InternalFacet {
|
|||
out.writeUTF(entry.toAsString);
|
||||
}
|
||||
out.writeVLong(entry.count);
|
||||
out.writeVLong(entry.totalCount);
|
||||
out.writeDouble(entry.total);
|
||||
out.writeDouble(entry.min);
|
||||
out.writeDouble(entry.max);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,7 +155,10 @@ public class InternalRangeFacet implements RangeFacet, InternalFacet {
|
|||
static final XContentBuilderString TO_STR = new XContentBuilderString("to_str");
|
||||
static final XContentBuilderString COUNT = new XContentBuilderString("count");
|
||||
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
|
||||
static final XContentBuilderString TOTAL_COUNT = new XContentBuilderString("total_count");
|
||||
static final XContentBuilderString MEAN = new XContentBuilderString("mean");
|
||||
static final XContentBuilderString MIN = new XContentBuilderString("min");
|
||||
static final XContentBuilderString MAX = new XContentBuilderString("max");
|
||||
}
|
||||
|
||||
@Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
|
@ -171,6 +180,9 @@ public class InternalRangeFacet implements RangeFacet, InternalFacet {
|
|||
builder.field(Fields.TO_STR, entry.toAsString);
|
||||
}
|
||||
builder.field(Fields.COUNT, entry.count());
|
||||
builder.field(Fields.MIN, entry.min());
|
||||
builder.field(Fields.MAX, entry.max());
|
||||
builder.field(Fields.TOTAL_COUNT, entry.totalCount());
|
||||
builder.field(Fields.TOTAL, entry.total());
|
||||
builder.field(Fields.MEAN, entry.mean());
|
||||
builder.endObject();
|
||||
|
|
|
@ -47,7 +47,6 @@ public class KeyValueRangeFacetCollector extends AbstractFacetCollector {
|
|||
private NumericFieldData keyFieldData;
|
||||
|
||||
private final FieldDataType valueFieldDataType;
|
||||
private NumericFieldData valueFieldData;
|
||||
|
||||
private final RangeFacet.Entry[] entries;
|
||||
|
||||
|
@ -117,12 +116,26 @@ public class KeyValueRangeFacetCollector extends AbstractFacetCollector {
|
|||
entry.count++;
|
||||
if (valueFieldData.multiValued()) {
|
||||
double[] valuesValues = valueFieldData.doubleValues(docId);
|
||||
entry.totalCount += valuesValues.length;
|
||||
for (double valueValue : valuesValues) {
|
||||
entry.total += valueValue;
|
||||
if (valueValue < entry.min) {
|
||||
entry.min = valueValue;
|
||||
}
|
||||
if (valueValue > entry.max) {
|
||||
entry.max = valueValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
double valueValue = valueFieldData.doubleValue(docId);
|
||||
entry.totalCount++;
|
||||
entry.total += valueValue;
|
||||
if (valueValue < entry.min) {
|
||||
entry.min = valueValue;
|
||||
}
|
||||
if (valueValue > entry.max) {
|
||||
entry.max = valueValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,8 +54,11 @@ public interface RangeFacet extends Facet, Iterable<RangeFacet.Entry> {
|
|||
String toAsString;
|
||||
|
||||
long count;
|
||||
long totalCount;
|
||||
|
||||
double total;
|
||||
double min = Double.MAX_VALUE;
|
||||
double max = Double.MIN_VALUE;
|
||||
|
||||
/**
|
||||
* Internal field used in facet collection
|
||||
|
@ -111,6 +114,14 @@ public interface RangeFacet extends Facet, Iterable<RangeFacet.Entry> {
|
|||
return count();
|
||||
}
|
||||
|
||||
public long totalCount() {
|
||||
return this.totalCount;
|
||||
}
|
||||
|
||||
public long getTotalCount() {
|
||||
return this.totalCount;
|
||||
}
|
||||
|
||||
public double total() {
|
||||
return this.total;
|
||||
}
|
||||
|
@ -123,7 +134,7 @@ public interface RangeFacet extends Facet, Iterable<RangeFacet.Entry> {
|
|||
* The mean of this facet interval.
|
||||
*/
|
||||
public double mean() {
|
||||
return total / count;
|
||||
return total / totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,5 +143,21 @@ public interface RangeFacet extends Facet, Iterable<RangeFacet.Entry> {
|
|||
public double getMean() {
|
||||
return mean();
|
||||
}
|
||||
|
||||
public double min() {
|
||||
return this.min;
|
||||
}
|
||||
|
||||
public double getMin() {
|
||||
return this.min;
|
||||
}
|
||||
|
||||
public double max() {
|
||||
return this.max;
|
||||
}
|
||||
|
||||
public double getMax() {
|
||||
return this.max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,14 @@ public class RangeFacetCollector extends AbstractFacetCollector {
|
|||
if (value >= entry.getFrom() && value < entry.getTo()) {
|
||||
entry.foundInDoc = true;
|
||||
entry.count++;
|
||||
entry.totalCount++;
|
||||
entry.total += value;
|
||||
if (value < entry.min) {
|
||||
entry.min = value;
|
||||
}
|
||||
if (value > entry.max) {
|
||||
entry.max = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,8 +159,17 @@ public class RangeFacetProcessor extends AbstractComponent implements FacetProce
|
|||
agg = geoDistanceFacet;
|
||||
} else {
|
||||
for (int i = 0; i < geoDistanceFacet.entries.length; i++) {
|
||||
agg.entries[i].count += geoDistanceFacet.entries[i].count;
|
||||
agg.entries[i].total += geoDistanceFacet.entries[i].total;
|
||||
RangeFacet.Entry aggEntry = agg.entries[i];
|
||||
RangeFacet.Entry currentEntry = geoDistanceFacet.entries[i];
|
||||
aggEntry.count += currentEntry.count;
|
||||
aggEntry.totalCount += currentEntry.totalCount;
|
||||
aggEntry.total += currentEntry.total;
|
||||
if (currentEntry.min < aggEntry.min) {
|
||||
aggEntry.min = currentEntry.min;
|
||||
}
|
||||
if (currentEntry.max > aggEntry.max) {
|
||||
aggEntry.max = currentEntry.max;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,14 @@ public class ScriptRangeFacetCollector extends AbstractFacetCollector {
|
|||
for (RangeFacet.Entry entry : entries) {
|
||||
if (key >= entry.getFrom() && key < entry.getTo()) {
|
||||
entry.count++;
|
||||
entry.totalCount++;
|
||||
entry.total += value;
|
||||
if (value < entry.min) {
|
||||
entry.min = value;
|
||||
}
|
||||
if (value > entry.max) {
|
||||
entry.max = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1113,16 +1113,25 @@ public class SimpleFacetsTests extends AbstractNodesTests {
|
|||
assertThat(facet.entries().get(0).to(), closeTo(1056, 0.000001));
|
||||
assertThat(Double.parseDouble(facet.entries().get(0).toAsString()), closeTo(1056, 0.000001));
|
||||
assertThat(facet.entries().get(0).count(), equalTo(1l));
|
||||
assertThat(facet.entries().get(0).totalCount(), equalTo(1l));
|
||||
assertThat(facet.entries().get(0).total(), closeTo(1055, 0.000001));
|
||||
assertThat(facet.entries().get(0).min(), closeTo(1055, 0.000001));
|
||||
assertThat(facet.entries().get(0).max(), closeTo(1055, 0.000001));
|
||||
assertThat(facet.entries().get(1).from(), closeTo(1000, 0.000001));
|
||||
assertThat(Double.parseDouble(facet.entries().get(1).fromAsString()), closeTo(1000, 0.000001));
|
||||
assertThat(facet.entries().get(1).to(), closeTo(1170, 0.000001));
|
||||
assertThat(Double.parseDouble(facet.entries().get(1).toAsString()), closeTo(1170, 0.000001));
|
||||
assertThat(facet.entries().get(1).count(), equalTo(2l));
|
||||
assertThat(facet.entries().get(1).totalCount(), equalTo(2l));
|
||||
assertThat(facet.entries().get(1).total(), closeTo(1055 + 1065, 0.000001));
|
||||
assertThat(facet.entries().get(1).min(), closeTo(1055, 0.000001));
|
||||
assertThat(facet.entries().get(1).max(), closeTo(1065, 0.000001));
|
||||
assertThat(facet.entries().get(2).from(), closeTo(1170, 0.000001));
|
||||
assertThat(facet.entries().get(2).count(), equalTo(1l));
|
||||
assertThat(facet.entries().get(2).totalCount(), equalTo(1l));
|
||||
assertThat(facet.entries().get(2).total(), closeTo(1175, 0.000001));
|
||||
assertThat(facet.entries().get(2).min(), closeTo(1175, 0.000001));
|
||||
assertThat(facet.entries().get(2).max(), closeTo(1175, 0.000001));
|
||||
|
||||
facet = searchResponse.facets().facet("range2");
|
||||
assertThat(facet.name(), equalTo("range2"));
|
||||
|
@ -1143,14 +1152,23 @@ public class SimpleFacetsTests extends AbstractNodesTests {
|
|||
assertThat(facet.entries().size(), equalTo(3));
|
||||
assertThat(facet.entries().get(0).to(), closeTo(1056, 0.000001));
|
||||
assertThat(facet.entries().get(0).count(), equalTo(1l));
|
||||
assertThat(facet.entries().get(0).totalCount(), equalTo(2l));
|
||||
assertThat(facet.entries().get(0).total(), closeTo(10 + 11, 0.000001));
|
||||
assertThat(facet.entries().get(0).min(), closeTo(10, 0.000001));
|
||||
assertThat(facet.entries().get(0).max(), closeTo(11, 0.000001));
|
||||
assertThat(facet.entries().get(1).from(), closeTo(1000, 0.000001));
|
||||
assertThat(facet.entries().get(1).to(), closeTo(1170, 0.000001));
|
||||
assertThat(facet.entries().get(1).count(), equalTo(2l));
|
||||
assertThat(facet.entries().get(1).totalCount(), equalTo(4l));
|
||||
assertThat(facet.entries().get(1).total(), closeTo(62, 0.000001));
|
||||
assertThat(facet.entries().get(1).min(), closeTo(10, 0.000001));
|
||||
assertThat(facet.entries().get(1).max(), closeTo(21, 0.000001));
|
||||
assertThat(facet.entries().get(2).from(), closeTo(1170, 0.000001));
|
||||
assertThat(facet.entries().get(2).count(), equalTo(1l));
|
||||
assertThat(facet.entries().get(2).totalCount(), equalTo(2l));
|
||||
assertThat(facet.entries().get(2).total(), closeTo(61, 0.000001));
|
||||
assertThat(facet.entries().get(2).min(), closeTo(30, 0.000001));
|
||||
assertThat(facet.entries().get(2).max(), closeTo(31, 0.000001));
|
||||
|
||||
facet = searchResponse.facets().facet("range4");
|
||||
assertThat(facet.name(), equalTo("range4"));
|
||||
|
|
Loading…
Reference in New Issue