Histogram Facet: Add min/max stats when providing value field / script, closes #830.

This commit is contained in:
kimchy 2011-04-04 23:48:54 +03:00
parent 46088b9f8a
commit 8d1e9dbd3c
8 changed files with 115 additions and 7 deletions

View File

@ -108,12 +108,18 @@ public class FullHistogramFacetCollector extends AbstractFacetCollector {
long bucket = bucket(value, interval);
InternalFullHistogramFacet.FullEntry entry = entries.get(bucket);
if (entry == null) {
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, 1, value);
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, value, value, 1, value);
entries.put(bucket, entry);
} else {
entry.count++;
entry.totalCount++;
entry.total += value;
if (value < entry.min) {
entry.min = value;
}
if (value > entry.max) {
entry.max = value;
}
}
}
}

View File

@ -186,5 +186,25 @@ public interface HistogramFacet extends Facet, Iterable<HistogramFacet.Entry> {
* The mean of this facet interval.
*/
double getMean();
/**
* The minimum value.
*/
double min();
/**
* The minimum value.
*/
double getMin();
/**
* The maximum value.
*/
double max();
/**
* The maximum value.
*/
double getMax();
}
}

View File

@ -105,6 +105,22 @@ public class InternalCountHistogramFacet extends InternalHistogramFacet {
@Override public double getMean() {
return mean();
}
@Override public double min() {
return Double.NaN;
}
@Override public double getMin() {
return Double.NaN;
}
@Override public double max() {
return Double.NaN;
}
@Override public double getMax() {
return Double.NaN;
}
}
private String name;

View File

@ -61,10 +61,14 @@ public class InternalFullHistogramFacet extends InternalHistogramFacet {
long count;
long totalCount;
double total;
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;
public FullEntry(long key, long count, long totalCount, double total) {
public FullEntry(long key, long count, double min, double max, long totalCount, double total) {
this.key = key;
this.count = count;
this.min = min;
this.max = max;
this.totalCount = totalCount;
this.total = total;
}
@ -108,6 +112,22 @@ public class InternalFullHistogramFacet extends InternalHistogramFacet {
@Override public double getMean() {
return total / totalCount;
}
@Override public double min() {
return this.min;
}
@Override public double getMin() {
return this.min;
}
@Override public double max() {
return this.max;
}
@Override public double getMax() {
return this.max;
}
}
private String name;
@ -178,6 +198,12 @@ public class InternalFullHistogramFacet extends InternalHistogramFacet {
current.count += fullEntry.count;
current.total += fullEntry.total;
current.totalCount += fullEntry.totalCount;
if (fullEntry.min < current.min) {
current.min = fullEntry.min;
}
if (fullEntry.max > current.max) {
current.max = fullEntry.max;
}
} else {
map.put(fullEntry.key, fullEntry);
}
@ -209,6 +235,8 @@ public class InternalFullHistogramFacet extends InternalHistogramFacet {
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 {
@ -219,6 +247,8 @@ public class InternalFullHistogramFacet extends InternalHistogramFacet {
builder.startObject();
builder.field(Fields.KEY, entry.key());
builder.field(Fields.COUNT, entry.count());
builder.field(Fields.MIN, entry.min());
builder.field(Fields.MAX, entry.max());
builder.field(Fields.TOTAL, entry.total());
builder.field(Fields.TOTAL_COUNT, entry.totalCount());
builder.field(Fields.MEAN, entry.mean());
@ -242,7 +272,7 @@ public class InternalFullHistogramFacet extends InternalHistogramFacet {
int size = in.readVInt();
entries = new ArrayList<FullEntry>(size);
for (int i = 0; i < size; i++) {
entries.add(new FullEntry(in.readLong(), in.readVLong(), in.readVLong(), in.readDouble()));
entries.add(new FullEntry(in.readLong(), in.readVLong(), in.readDouble(), in.readDouble(), in.readVLong(), in.readDouble()));
}
}
@ -254,6 +284,8 @@ public class InternalFullHistogramFacet extends InternalHistogramFacet {
for (FullEntry entry : entries) {
out.writeLong(entry.key);
out.writeVLong(entry.count);
out.writeDouble(entry.min);
out.writeDouble(entry.max);
out.writeVLong(entry.totalCount);
out.writeDouble(entry.total);
}

View File

@ -119,14 +119,20 @@ public class KeyValueHistogramFacetCollector extends AbstractFacetCollector {
if (entry == null) {
if (valueFieldData.multiValued()) {
double[] valuesValues = valueFieldData.doubleValues(docId);
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, valuesValues.length, 0);
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, Double.MAX_VALUE, Double.MIN_VALUE, valuesValues.length, 0);
for (double valueValue : valuesValues) {
entry.total += valueValue;
if (valueValue < entry.min) {
entry.min = valueValue;
}
if (valueValue > entry.max) {
entry.max = valueValue;
}
}
entries.put(bucket, entry);
} else {
double valueValue = valueFieldData.doubleValue(docId);
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, 1, valueValue);
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, valueValue, valueValue, 1, valueValue);
entries.put(bucket, entry);
}
} else {
@ -136,11 +142,23 @@ public class KeyValueHistogramFacetCollector extends AbstractFacetCollector {
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 {
entry.totalCount++;
double valueValue = valueFieldData.doubleValue(docId);
entry.total += valueValue;
if (valueValue < entry.min) {
entry.min = valueValue;
}
if (valueValue > entry.max) {
entry.max = valueValue;
}
}
}
}

View File

@ -126,12 +126,18 @@ public class KeyValueScriptHistogramFacetCollector extends AbstractFacetCollecto
InternalFullHistogramFacet.FullEntry entry = entries.get(bucket);
if (entry == null) {
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, 1, scriptValue);
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, scriptValue, scriptValue, 1, scriptValue);
entries.put(bucket, entry);
} else {
entry.count++;
entry.totalCount++;
entry.total += scriptValue;
if (scriptValue < entry.min) {
entry.min = scriptValue;
}
if (scriptValue > entry.max) {
entry.max = scriptValue;
}
}
}
}

View File

@ -67,12 +67,18 @@ public class ScriptHistogramFacetCollector extends AbstractFacetCollector {
InternalFullHistogramFacet.FullEntry entry = entries.get(bucket);
if (entry == null) {
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, 1, value);
entry = new InternalFullHistogramFacet.FullEntry(bucket, 1, value, value, 1, value);
entries.put(bucket, entry);
} else {
entry.count++;
entry.totalCount++;
entry.total += value;
if (value < entry.min) {
entry.min = value;
}
if (value > entry.max) {
entry.max = value;
}
}
}

View File

@ -948,11 +948,15 @@ public class SimpleFacetsTests extends AbstractNodesTests {
assertThat(facet.entries().size(), equalTo(2));
assertThat(facet.entries().get(0).key(), equalTo(1000l));
assertThat(facet.entries().get(0).count(), equalTo(2l));
assertThat(facet.entries().get(0).min(), closeTo(1055d, 0.000001));
assertThat(facet.entries().get(0).max(), closeTo(1065d, 0.000001));
assertThat(facet.entries().get(0).totalCount(), equalTo(2l));
assertThat(facet.entries().get(0).total(), equalTo(2120d));
assertThat(facet.entries().get(0).mean(), equalTo(1060d));
assertThat(facet.entries().get(1).key(), equalTo(1100l));
assertThat(facet.entries().get(1).count(), equalTo(1l));
assertThat(facet.entries().get(1).min(), closeTo(1175d, 0.000001));
assertThat(facet.entries().get(1).max(), closeTo(1175d, 0.000001));
assertThat(facet.entries().get(1).totalCount(), equalTo(1l));
assertThat(facet.entries().get(1).total(), equalTo(1175d));
assertThat(facet.entries().get(1).mean(), equalTo(1175d));