add min/max to terms stats facet

This commit is contained in:
kimchy 2011-02-23 20:36:12 +02:00
parent bcaeb226d5
commit 8371920a89
8 changed files with 275 additions and 24 deletions

View File

@ -160,7 +160,68 @@ public interface TermsStatsFacet extends Facet, Iterable<TermsStatsFacet.Entry>
}
return -TOTAL.comparator().compare(o1, o2);
}
});
}),
MIN((byte) 6, new Comparator<Entry>() {
@Override public int compare(Entry o1, Entry o2) {
// push nulls to the end
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
if (o1.min() < o2.min()) {
return -1;
} else if (o1.min() == o2.min()) {
return COUNT.comparator().compare(o1, o2);
} else {
return 1;
}
}
}),
REVERSE_MIN((byte) 7, new Comparator<Entry>() {
@Override public int compare(Entry o1, Entry o2) {
// push nulls to the end
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
return -MIN.comparator().compare(o1, o2);
}
}),
MAX((byte) 8, new Comparator<Entry>() {
@Override public int compare(Entry o1, Entry o2) {
// push nulls to the end
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
if (o2.max() < o1.max()) {
return -1;
} else if (o1.max() == o2.max()) {
return COUNT.comparator().compare(o1, o2);
} else {
return 1;
}
}
}),
REVERSE_MAX((byte) 9, new Comparator<Entry>() {
@Override public int compare(Entry o1, Entry o2) {
// push nulls to the end
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
return -MAX.comparator().compare(o1, o2);
}
}),;
private final byte id;
@ -192,6 +253,14 @@ public interface TermsStatsFacet extends Facet, Iterable<TermsStatsFacet.Entry>
return TOTAL;
} else if (id == REVERSE_TOTAL.id()) {
return REVERSE_TOTAL;
} else if (id == MIN.id()) {
return MIN;
} else if (id == REVERSE_MIN.id()) {
return REVERSE_MIN;
} else if (id == MAX.id()) {
return MAX;
} else if (id == REVERSE_MAX.id()) {
return REVERSE_MAX;
}
throw new ElasticSearchIllegalArgumentException("No type argument match for terms facet comparator [" + id + "]");
}
@ -209,6 +278,14 @@ public interface TermsStatsFacet extends Facet, Iterable<TermsStatsFacet.Entry>
return TOTAL;
} else if ("reverse_total".equals(type) || "reverseTotal".equals(type)) {
return REVERSE_TOTAL;
} else if ("min".equals(type)) {
return MIN;
} else if ("reverse_min".equals(type) || "reverseMin".equals(type)) {
return REVERSE_MIN;
} else if ("max".equals(type)) {
return MAX;
} else if ("reverse_max".equals(type) || "reverseMax".equals(type)) {
return REVERSE_MAX;
}
throw new ElasticSearchIllegalArgumentException("No type argument match for terms stats facet comparator [" + type + "]");
}
@ -228,6 +305,14 @@ public interface TermsStatsFacet extends Facet, Iterable<TermsStatsFacet.Entry>
int getCount();
double min();
double getMin();
double max();
double getMax();
double total();
double getTotal();

View File

@ -58,11 +58,15 @@ public class InternalTermsStatsDoubleFacet extends InternalTermsStatsFacet {
double term;
int count;
double total;
double min;
double max;
public DoubleEntry(double term, int count, double total) {
public DoubleEntry(double term, int count, double total, double min, double max) {
this.term = term;
this.count = count;
this.total = total;
this.min = min;
this.max = max;
}
@Override public String term() {
@ -89,6 +93,22 @@ public class InternalTermsStatsDoubleFacet extends InternalTermsStatsFacet {
return count();
}
@Override public double min() {
return this.min;
}
@Override public double getMin() {
return min();
}
@Override public double max() {
return max;
}
@Override public double getMax() {
return max();
}
@Override public double total() {
return total;
}
@ -205,6 +225,12 @@ public class InternalTermsStatsDoubleFacet extends InternalTermsStatsFacet {
if (current != null) {
current.count += doubleEntry.count;
current.total += doubleEntry.total;
if (doubleEntry.min < current.min || Double.isNaN(current.min)) {
current.min = doubleEntry.min;
}
if (doubleEntry.max > current.max || Double.isNaN(current.max)) {
current.max = doubleEntry.max;
}
} else {
map.put(doubleEntry.term, doubleEntry);
}
@ -237,6 +263,8 @@ public class InternalTermsStatsDoubleFacet extends InternalTermsStatsFacet {
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
static final XContentBuilderString MIN = new XContentBuilderString("min");
static final XContentBuilderString MAX = new XContentBuilderString("max");
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
static final XContentBuilderString MEAN = new XContentBuilderString("mean");
}
@ -250,6 +278,8 @@ public class InternalTermsStatsDoubleFacet extends InternalTermsStatsFacet {
builder.startObject();
builder.field(Fields.TERM, ((DoubleEntry) entry).term);
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.MEAN, entry.mean());
builder.endObject();
@ -274,7 +304,7 @@ public class InternalTermsStatsDoubleFacet extends InternalTermsStatsFacet {
int size = in.readVInt();
entries = new ArrayList<DoubleEntry>(size);
for (int i = 0; i < size; i++) {
entries.add(new DoubleEntry(in.readDouble(), in.readVInt(), in.readDouble()));
entries.add(new DoubleEntry(in.readDouble(), in.readVInt(), in.readDouble(), in.readDouble(), in.readDouble()));
}
}
@ -289,6 +319,8 @@ public class InternalTermsStatsDoubleFacet extends InternalTermsStatsFacet {
out.writeDouble(((DoubleEntry) entry).term);
out.writeVInt(entry.count());
out.writeDouble(entry.total());
out.writeDouble(entry.min());
out.writeDouble(entry.max());
}
}
}

View File

@ -129,26 +129,44 @@ public class TermsStatsDoubleFacetCollector extends AbstractFacetCollector {
return;
}
double key = keyFieldData.doubleValue(doc);
InternalTermsStatsDoubleFacet.DoubleEntry DoubleEntry = entries.get(key);
if (DoubleEntry == null) {
DoubleEntry = new InternalTermsStatsDoubleFacet.DoubleEntry(key, 1, 0);
entries.put(key, DoubleEntry);
InternalTermsStatsDoubleFacet.DoubleEntry doubleEntry = entries.get(key);
if (doubleEntry == null) {
doubleEntry = new InternalTermsStatsDoubleFacet.DoubleEntry(key, 1, 0, Double.NaN, Double.NaN);
entries.put(key, doubleEntry);
} else {
DoubleEntry.count++;
doubleEntry.count++;
}
if (script == null) {
if (valueFieldData.multiValued()) {
for (double value : valueFieldData.doubleValues(doc)) {
DoubleEntry.total += value;
if (value < doubleEntry.min || Double.isNaN(doubleEntry.min)) {
doubleEntry.min = value;
}
if (value > doubleEntry.max || Double.isNaN(doubleEntry.max)) {
doubleEntry.max = value;
}
doubleEntry.total += value;
}
} else {
double value = valueFieldData.doubleValue(doc);
DoubleEntry.total += value;
if (value < doubleEntry.min || Double.isNaN(doubleEntry.min)) {
doubleEntry.min = value;
}
if (value > doubleEntry.max || Double.isNaN(doubleEntry.max)) {
doubleEntry.max = value;
}
doubleEntry.total += value;
}
} else {
script.setNextDocId(doc);
double value = script.runAsDouble();
DoubleEntry.total += value;
if (value < doubleEntry.min || Double.isNaN(doubleEntry.min)) {
doubleEntry.min = value;
}
if (value > doubleEntry.max || Double.isNaN(doubleEntry.max)) {
doubleEntry.max = value;
}
doubleEntry.total += value;
}
}

View File

@ -58,11 +58,15 @@ public class InternalTermsStatsLongFacet extends InternalTermsStatsFacet {
long term;
int count;
double total;
double min;
double max;
public LongEntry(long term, int count, double total) {
public LongEntry(long term, int count, double total, double min, double max) {
this.term = term;
this.count = count;
this.total = total;
this.min = min;
this.max = max;
}
@Override public String term() {
@ -89,6 +93,22 @@ public class InternalTermsStatsLongFacet extends InternalTermsStatsFacet {
return count();
}
@Override public double min() {
return this.min;
}
@Override public double getMin() {
return min();
}
@Override public double max() {
return max;
}
@Override public double getMax() {
return max();
}
@Override public double total() {
return total;
}
@ -205,6 +225,12 @@ public class InternalTermsStatsLongFacet extends InternalTermsStatsFacet {
if (current != null) {
current.count += longEntry.count;
current.total += longEntry.total;
if (longEntry.min < current.min || Double.isNaN(current.min)) {
current.min = longEntry.min;
}
if (longEntry.max > current.max || Double.isNaN(current.max)) {
current.max = longEntry.max;
}
} else {
map.put(longEntry.term, longEntry);
}
@ -237,6 +263,8 @@ public class InternalTermsStatsLongFacet extends InternalTermsStatsFacet {
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
static final XContentBuilderString MIN = new XContentBuilderString("min");
static final XContentBuilderString MAX = new XContentBuilderString("max");
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
static final XContentBuilderString MEAN = new XContentBuilderString("mean");
}
@ -250,6 +278,8 @@ public class InternalTermsStatsLongFacet extends InternalTermsStatsFacet {
builder.startObject();
builder.field(Fields.TERM, ((LongEntry) entry).term);
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.MEAN, entry.mean());
builder.endObject();
@ -274,7 +304,7 @@ public class InternalTermsStatsLongFacet extends InternalTermsStatsFacet {
int size = in.readVInt();
entries = new ArrayList<LongEntry>(size);
for (int i = 0; i < size; i++) {
entries.add(new LongEntry(in.readLong(), in.readVInt(), in.readDouble()));
entries.add(new LongEntry(in.readLong(), in.readVInt(), in.readDouble(), in.readDouble(), in.readDouble()));
}
}
@ -289,6 +319,8 @@ public class InternalTermsStatsLongFacet extends InternalTermsStatsFacet {
out.writeLong(((LongEntry) entry).term);
out.writeVInt(entry.count());
out.writeDouble(entry.total());
out.writeDouble(entry.min());
out.writeDouble(entry.max());
}
}
}

View File

@ -129,26 +129,44 @@ public class TermsStatsLongFacetCollector extends AbstractFacetCollector {
return;
}
long key = keyFieldData.longValue(doc);
InternalTermsStatsLongFacet.LongEntry LongEntry = entries.get(key);
if (LongEntry == null) {
LongEntry = new InternalTermsStatsLongFacet.LongEntry(key, 1, 0);
entries.put(key, LongEntry);
InternalTermsStatsLongFacet.LongEntry longEntry = entries.get(key);
if (longEntry == null) {
longEntry = new InternalTermsStatsLongFacet.LongEntry(key, 1, 0, Double.NaN, Double.NaN);
entries.put(key, longEntry);
} else {
LongEntry.count++;
longEntry.count++;
}
if (script == null) {
if (valueFieldData.multiValued()) {
for (double value : valueFieldData.doubleValues(doc)) {
LongEntry.total += value;
if (value < longEntry.min || Double.isNaN(longEntry.min)) {
longEntry.min = value;
}
if (value > longEntry.max || Double.isNaN(longEntry.max)) {
longEntry.max = value;
}
longEntry.total += value;
}
} else {
double value = valueFieldData.doubleValue(doc);
LongEntry.total += value;
if (value < longEntry.min || Double.isNaN(longEntry.min)) {
longEntry.min = value;
}
if (value > longEntry.max || Double.isNaN(longEntry.max)) {
longEntry.max = value;
}
longEntry.total += value;
}
} else {
script.setNextDocId(doc);
double value = script.runAsDouble();
LongEntry.total += value;
if (value < longEntry.min || Double.isNaN(longEntry.min)) {
longEntry.min = value;
}
if (value > longEntry.max || Double.isNaN(longEntry.max)) {
longEntry.max = value;
}
longEntry.total += value;
}
}

View File

@ -58,11 +58,15 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
String term;
int count;
double total;
double min;
double max;
public StringEntry(String term, int count, double total) {
public StringEntry(String term, int count, double total, double min, double max) {
this.term = term;
this.count = count;
this.total = total;
this.min = min;
this.max = max;
}
@Override public String term() {
@ -89,6 +93,22 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
return count();
}
@Override public double min() {
return this.min;
}
@Override public double getMin() {
return min();
}
@Override public double max() {
return this.max;
}
@Override public double getMax() {
return max();
}
@Override public double total() {
return total;
}
@ -204,6 +224,12 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
if (current != null) {
current.count += stringEntry.count;
current.total += stringEntry.total;
if (stringEntry.min < current.min || Double.isNaN(current.min)) {
current.min = stringEntry.min;
}
if (stringEntry.max > current.max || Double.isNaN(current.max)) {
current.max = stringEntry.max;
}
} else {
map.put(stringEntry.term(), stringEntry);
}
@ -237,6 +263,8 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
static final XContentBuilderString MIN = new XContentBuilderString("min");
static final XContentBuilderString MAX = new XContentBuilderString("max");
static final XContentBuilderString MEAN = new XContentBuilderString("mean");
}
@ -249,6 +277,8 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
builder.startObject();
builder.field(Fields.TERM, entry.term());
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.MEAN, entry.mean());
builder.endObject();
@ -273,7 +303,7 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
int size = in.readVInt();
entries = new ArrayList<StringEntry>(size);
for (int i = 0; i < size; i++) {
entries.add(new StringEntry(in.readUTF(), in.readVInt(), in.readDouble()));
entries.add(new StringEntry(in.readUTF(), in.readVInt(), in.readDouble(), in.readDouble(), in.readDouble()));
}
}
@ -288,6 +318,8 @@ public class InternalTermsStatsStringFacet extends InternalTermsStatsFacet {
out.writeUTF(entry.term());
out.writeVInt(entry.count());
out.writeDouble(entry.total());
out.writeDouble(entry.min());
out.writeDouble(entry.max());
}
}
}

View File

@ -132,7 +132,7 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
String key = keyFieldData.stringValue(doc);
InternalTermsStatsStringFacet.StringEntry stringEntry = entries.get(key);
if (stringEntry == null) {
stringEntry = new InternalTermsStatsStringFacet.StringEntry(key, 1, 0);
stringEntry = new InternalTermsStatsStringFacet.StringEntry(key, 1, 0, Double.NaN, Double.NaN);
entries.put(key, stringEntry);
} else {
stringEntry.count++;
@ -140,15 +140,33 @@ public class TermsStatsStringFacetCollector extends AbstractFacetCollector {
if (script == null) {
if (valueFieldData.multiValued()) {
for (double value : valueFieldData.doubleValues(doc)) {
if (value < stringEntry.min || Double.isNaN(stringEntry.min)) {
stringEntry.min = value;
}
if (value > stringEntry.max || Double.isNaN(stringEntry.max)) {
stringEntry.max = value;
}
stringEntry.total += value;
}
} else {
double value = valueFieldData.doubleValue(doc);
if (value < stringEntry.min || Double.isNaN(stringEntry.min)) {
stringEntry.min = value;
}
if (value > stringEntry.max || Double.isNaN(stringEntry.max)) {
stringEntry.max = value;
}
stringEntry.total += value;
}
} else {
script.setNextDocId(doc);
double value = script.runAsDouble();
if (value < stringEntry.min || Double.isNaN(stringEntry.min)) {
stringEntry.min = value;
}
if (value > stringEntry.max || Double.isNaN(stringEntry.max)) {
stringEntry.max = value;
}
stringEntry.total += value;
}
}

View File

@ -1335,18 +1335,26 @@ public class SimpleFacetsTests extends AbstractNodesTests {
assertThat(facet.entries().size(), equalTo(2));
assertThat(facet.entries().get(0).term(), equalTo("xxx"));
assertThat(facet.entries().get(0).count(), equalTo(2));
assertThat(facet.entries().get(0).min(), closeTo(100d, 0.00001d));
assertThat(facet.entries().get(0).max(), closeTo(200d, 0.00001d));
assertThat(facet.entries().get(0).total(), closeTo(300d, 0.00001d));
assertThat(facet.entries().get(1).term(), equalTo("yyy"));
assertThat(facet.entries().get(1).count(), equalTo(1));
assertThat(facet.entries().get(1).min(), closeTo(500d, 0.00001d));
assertThat(facet.entries().get(1).max(), closeTo(500d, 0.00001d));
assertThat(facet.entries().get(1).total(), closeTo(500d, 0.00001d));
facet = searchResponse.facets().facet("stats2");
assertThat(facet.entries().size(), equalTo(2));
assertThat(facet.entries().get(0).term(), equalTo("xxx"));
assertThat(facet.entries().get(0).count(), equalTo(2));
assertThat(facet.entries().get(0).min(), closeTo(1d, 0.00001d));
assertThat(facet.entries().get(0).max(), closeTo(3d, 0.00001d));
assertThat(facet.entries().get(0).total(), closeTo(8d, 0.00001d));
assertThat(facet.entries().get(1).term(), equalTo("yyy"));
assertThat(facet.entries().get(1).count(), equalTo(1));
assertThat(facet.entries().get(1).min(), closeTo(5d, 0.00001d));
assertThat(facet.entries().get(1).max(), closeTo(6d, 0.00001d));
assertThat(facet.entries().get(1).total(), closeTo(11d, 0.00001d));
facet = searchResponse.facets().facet("stats3");
@ -1496,18 +1504,26 @@ public class SimpleFacetsTests extends AbstractNodesTests {
assertThat(facet.entries().size(), equalTo(2));
assertThat(facet.entries().get(0).term(), equalTo("100"));
assertThat(facet.entries().get(0).count(), equalTo(2));
assertThat(facet.entries().get(0).min(), closeTo(100d, 0.00001d));
assertThat(facet.entries().get(0).max(), closeTo(200d, 0.00001d));
assertThat(facet.entries().get(0).total(), closeTo(300d, 0.00001d));
assertThat(facet.entries().get(1).term(), equalTo("200"));
assertThat(facet.entries().get(1).count(), equalTo(1));
assertThat(facet.entries().get(1).min(), closeTo(500d, 0.00001d));
assertThat(facet.entries().get(1).max(), closeTo(500d, 0.00001d));
assertThat(facet.entries().get(1).total(), closeTo(500d, 0.00001d));
facet = searchResponse.facets().facet("stats2");
assertThat(facet.entries().size(), equalTo(2));
assertThat(facet.entries().get(0).term(), equalTo("100.1"));
assertThat(facet.entries().get(0).count(), equalTo(2));
assertThat(facet.entries().get(0).min(), closeTo(100d, 0.00001d));
assertThat(facet.entries().get(0).max(), closeTo(200d, 0.00001d));
assertThat(facet.entries().get(0).total(), closeTo(300d, 0.00001d));
assertThat(facet.entries().get(1).term(), equalTo("200.2"));
assertThat(facet.entries().get(1).count(), equalTo(1));
assertThat(facet.entries().get(1).min(), closeTo(500d, 0.00001d));
assertThat(facet.entries().get(1).max(), closeTo(500d, 0.00001d));
assertThat(facet.entries().get(1).total(), closeTo(500d, 0.00001d));
}