Geo Distance Facet: Fix wrong total computation with multi valued fields by introducing total_count, add min/max stats, closes #833.
This commit is contained in:
parent
79939222e4
commit
cea8c5fefa
|
@ -51,7 +51,10 @@ public interface GeoDistanceFacet extends Facet, Iterable<GeoDistanceFacet.Entry
|
|||
|
||||
long count;
|
||||
|
||||
long totalCount;
|
||||
double total;
|
||||
double min = Double.MAX_VALUE;
|
||||
double max = Double.MIN_VALUE;
|
||||
|
||||
/**
|
||||
* internal field used to see if this entry was already found for a doc
|
||||
|
@ -61,11 +64,14 @@ public interface GeoDistanceFacet extends Facet, Iterable<GeoDistanceFacet.Entry
|
|||
Entry() {
|
||||
}
|
||||
|
||||
public Entry(double from, double to, long count, double total) {
|
||||
public Entry(double from, double to, long count, long totalCount, double total, double min, double max) {
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.count = count;
|
||||
this.totalCount = totalCount;
|
||||
this.total = total;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public double from() {
|
||||
|
@ -92,6 +98,14 @@ public interface GeoDistanceFacet extends Facet, Iterable<GeoDistanceFacet.Entry
|
|||
return count();
|
||||
}
|
||||
|
||||
public long totalCount() {
|
||||
return this.totalCount;
|
||||
}
|
||||
|
||||
public long getTotalCount() {
|
||||
return this.totalCount;
|
||||
}
|
||||
|
||||
public double total() {
|
||||
return this.total;
|
||||
}
|
||||
|
@ -104,7 +118,7 @@ public interface GeoDistanceFacet extends Facet, Iterable<GeoDistanceFacet.Entry
|
|||
* The mean of this facet interval.
|
||||
*/
|
||||
public double mean() {
|
||||
return total / count;
|
||||
return total / totalCount;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -113,5 +127,21 @@ public interface GeoDistanceFacet extends Facet, Iterable<GeoDistanceFacet.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,14 @@ public class GeoDistanceFacetCollector extends AbstractFacetCollector {
|
|||
if (distance >= entry.getFrom() && distance < entry.getTo()) {
|
||||
entry.foundInDoc = true;
|
||||
entry.count++;
|
||||
entry.totalCount++;
|
||||
entry.total += distance;
|
||||
if (distance < entry.min) {
|
||||
entry.min = distance;
|
||||
}
|
||||
if (distance > entry.max) {
|
||||
entry.max = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ public class GeoDistanceFacetProcessor extends AbstractComponent implements Face
|
|||
}
|
||||
}
|
||||
}
|
||||
entries.add(new GeoDistanceFacet.Entry(from, to, 0, 0));
|
||||
entries.add(new GeoDistanceFacet.Entry(from, to, 0, 0, 0, Double.MAX_VALUE, Double.MIN_VALUE));
|
||||
}
|
||||
} else {
|
||||
token = parser.nextToken();
|
||||
|
@ -183,8 +183,17 @@ public class GeoDistanceFacetProcessor extends AbstractComponent implements Face
|
|||
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;
|
||||
GeoDistanceFacet.Entry aggEntry = agg.entries[i];
|
||||
GeoDistanceFacet.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ public class InternalGeoDistanceFacet implements GeoDistanceFacet, InternalFacet
|
|||
name = in.readUTF();
|
||||
entries = new Entry[in.readVInt()];
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
entries[i] = new Entry(in.readDouble(), in.readDouble(), in.readVLong(), in.readDouble());
|
||||
entries[i] = new Entry(in.readDouble(), in.readDouble(), in.readVLong(), in.readVLong(), in.readDouble(), in.readDouble(), in.readDouble());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,10 @@ public class InternalGeoDistanceFacet implements GeoDistanceFacet, InternalFacet
|
|||
out.writeDouble(entry.from);
|
||||
out.writeDouble(entry.to);
|
||||
out.writeVLong(entry.count);
|
||||
out.writeVLong(entry.totalCount);
|
||||
out.writeDouble(entry.total);
|
||||
out.writeDouble(entry.min);
|
||||
out.writeDouble(entry.max);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,8 +127,11 @@ public class InternalGeoDistanceFacet implements GeoDistanceFacet, InternalFacet
|
|||
static final XContentBuilderString FROM = new XContentBuilderString("from");
|
||||
static final XContentBuilderString TO = new XContentBuilderString("to");
|
||||
static final XContentBuilderString COUNT = new XContentBuilderString("count");
|
||||
static final XContentBuilderString TOTAL_COUNT = new XContentBuilderString("total_count");
|
||||
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
|
||||
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 {
|
||||
|
@ -140,7 +146,9 @@ public class InternalGeoDistanceFacet implements GeoDistanceFacet, InternalFacet
|
|||
if (!Double.isInfinite(entry.to)) {
|
||||
builder.field(Fields.TO, entry.to);
|
||||
}
|
||||
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();
|
||||
|
|
|
@ -95,7 +95,14 @@ public class ScriptGeoDistanceFacetCollector extends GeoDistanceFacetCollector {
|
|||
if (distance >= entry.getFrom() && distance < entry.getTo()) {
|
||||
entry.foundInDoc = true;
|
||||
entry.count++;
|
||||
entry.totalCount++;
|
||||
entry.total += scriptValue;
|
||||
if (scriptValue < entry.min) {
|
||||
entry.min = scriptValue;
|
||||
}
|
||||
if (scriptValue > entry.max) {
|
||||
entry.max = scriptValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,11 +91,26 @@ public class ValueGeoDistanceFacetCollector extends GeoDistanceFacetCollector {
|
|||
entry.count++;
|
||||
if (valueFieldData.multiValued()) {
|
||||
double[] values = valueFieldData.doubleValues(docId);
|
||||
entry.totalCount += values.length;
|
||||
for (double value : values) {
|
||||
entry.total += value;
|
||||
if (value < entry.min) {
|
||||
entry.min = value;
|
||||
}
|
||||
if (value > entry.max) {
|
||||
entry.max = value;
|
||||
}
|
||||
}
|
||||
} else if (valueFieldData.hasValue(docId)) {
|
||||
entry.total += valueFieldData.doubleValue(docId);
|
||||
entry.totalCount++;
|
||||
double value = valueFieldData.doubleValue(docId);
|
||||
entry.total += value;
|
||||
if (value < entry.min) {
|
||||
entry.min = value;
|
||||
}
|
||||
if (value > entry.max) {
|
||||
entry.max = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue