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:
kimchy 2011-04-05 00:52:58 +03:00
parent 79939222e4
commit cea8c5fefa
6 changed files with 84 additions and 8 deletions

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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();

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}
}
}