Terms Facet: Add option include counts where term is missing, closes #632.

This commit is contained in:
kimchy 2011-01-18 21:51:16 +02:00
parent e4a6e99f69
commit 574c455203
49 changed files with 464 additions and 35 deletions

View File

@ -91,6 +91,8 @@ public abstract class FieldData<Doc extends DocFieldData> {
public static interface StringValueInDocProc {
void onValue(int docId, String value);
void onMissing(int docId);
}
/**

View File

@ -96,5 +96,7 @@ public abstract class NumericFieldData<Doc extends NumericDocFieldData> extends
public static interface DoubleValueInDocProc {
void onValue(int docId, double value);
void onMissing(int docId);
}
}

View File

@ -111,6 +111,8 @@ public abstract class ByteFieldData extends NumericFieldData<ByteDocFieldData> {
public static interface ValueInDocProc {
void onValue(int docId, byte value);
void onMissing(int docID);
}
public static ByteFieldData load(IndexReader reader, String field) throws IOException {

View File

@ -81,30 +81,45 @@ public class MultiValueByteFieldData extends ByteFieldData {
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, Byte.toString(values[loc]));
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public double[] doubleValues(int docId) {

View File

@ -64,6 +64,7 @@ public class SingleValueByteFieldData extends ByteFieldData {
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, Byte.toString(values[loc]));
@ -72,6 +73,7 @@ public class SingleValueByteFieldData extends ByteFieldData {
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);
@ -80,6 +82,7 @@ public class SingleValueByteFieldData extends ByteFieldData {
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);

View File

@ -111,6 +111,8 @@ public abstract class DoubleFieldData extends NumericFieldData<DoubleDocFieldDat
public static interface ValueInDocProc {
void onValue(int docId, double value);
void onMissing(int docId);
}
public static DoubleFieldData load(IndexReader reader, String field) throws IOException {

View File

@ -70,30 +70,45 @@ public class MultiValueDoubleFieldData extends DoubleFieldData {
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, Double.toString(values[loc]));
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public double[] doubleValues(int docId) {

View File

@ -57,6 +57,7 @@ public class SingleValueDoubleFieldData extends DoubleFieldData {
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, Double.toString(values[loc]));
@ -65,6 +66,7 @@ public class SingleValueDoubleFieldData extends DoubleFieldData {
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);
@ -73,6 +75,7 @@ public class SingleValueDoubleFieldData extends DoubleFieldData {
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);

View File

@ -111,6 +111,8 @@ public abstract class FloatFieldData extends NumericFieldData<FloatDocFieldData>
public static interface ValueInDocProc {
void onValue(int docId, float value);
void onMissing(int docId);
}
public static FloatFieldData load(IndexReader reader, String field) throws IOException {

View File

@ -81,30 +81,45 @@ public class MultiValueFloatFieldData extends FloatFieldData {
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, Float.toString(values[loc]));
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public double[] doubleValues(int docId) {

View File

@ -64,6 +64,7 @@ public class SingleValueFloatFieldData extends FloatFieldData {
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, Float.toString(values[loc]));
@ -72,6 +73,7 @@ public class SingleValueFloatFieldData extends FloatFieldData {
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);
@ -80,6 +82,7 @@ public class SingleValueFloatFieldData extends FloatFieldData {
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);

View File

@ -111,6 +111,8 @@ public abstract class IntFieldData extends NumericFieldData<IntDocFieldData> {
public static interface ValueInDocProc {
void onValue(int docId, int value);
void onMissing(int docId);
}
public static IntFieldData load(IndexReader reader, String field) throws IOException {

View File

@ -81,30 +81,45 @@ public class MultiValueIntFieldData extends IntFieldData {
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, Integer.toString(values[loc]));
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public double[] doubleValues(int docId) {

View File

@ -64,6 +64,7 @@ public class SingleValueIntFieldData extends IntFieldData {
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, Integer.toString(values[loc]));
@ -72,6 +73,7 @@ public class SingleValueIntFieldData extends IntFieldData {
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);
@ -80,6 +82,7 @@ public class SingleValueIntFieldData extends IntFieldData {
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);

View File

@ -133,6 +133,8 @@ public abstract class LongFieldData extends NumericFieldData<LongDocFieldData> {
public static interface ValueInDocProc {
void onValue(int docId, long value);
void onMissing(int docId);
}
public abstract void forEachValueInDoc(int docId, DateValueInDocProc proc);

View File

@ -97,30 +97,45 @@ public class MultiValueLongFieldData extends LongFieldData {
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, Long.toString(values[loc]));
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, DateValueInDocProc proc) {

View File

@ -74,6 +74,7 @@ public class SingleValueLongFieldData extends LongFieldData {
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, Long.toString(values[loc]));
@ -82,6 +83,7 @@ public class SingleValueLongFieldData extends LongFieldData {
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);
@ -90,6 +92,7 @@ public class SingleValueLongFieldData extends LongFieldData {
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);

View File

@ -81,30 +81,45 @@ public class MultiValueShortFieldData extends ShortFieldData {
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, Short.toString(values[loc]));
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public double[] doubleValues(int docId) {

View File

@ -111,6 +111,8 @@ public abstract class ShortFieldData extends NumericFieldData<ShortDocFieldData>
public static interface ValueInDocProc {
void onValue(int docId, short value);
void onMissing(int docId);
}
public static ShortFieldData load(IndexReader reader, String field) throws IOException {

View File

@ -64,6 +64,7 @@ public class SingleValueShortFieldData extends ShortFieldData {
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, Short.toString(values[loc]));
@ -72,6 +73,7 @@ public class SingleValueShortFieldData extends ShortFieldData {
@Override public void forEachValueInDoc(int docId, DoubleValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);
@ -80,6 +82,7 @@ public class SingleValueShortFieldData extends ShortFieldData {
@Override public void forEachValueInDoc(int docId, ValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);

View File

@ -71,12 +71,17 @@ public class MultiValueStringFieldData extends StringFieldData {
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, values[loc]);
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public String value(int docId) {

View File

@ -66,6 +66,7 @@ public class SingleValueStringFieldData extends StringFieldData {
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, values[loc]);

View File

@ -95,12 +95,17 @@ public class MultiValueGeoPointFieldData extends GeoPointFieldData {
}
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
boolean found = false;
for (int[] ordinal : ordinals) {
int loc = ordinal[docId];
if (loc != 0) {
found = true;
proc.onValue(docId, GeoHashUtils.encode(lat[loc], lon[loc]));
}
}
if (!found) {
proc.onMissing(docId);
}
}
@Override public GeoPoint value(int docId) {

View File

@ -74,6 +74,7 @@ public class SingleValueGeoPointFieldData extends GeoPointFieldData {
@Override public void forEachValueInDoc(int docId, StringValueInDocProc proc) {
int loc = ordinals[docId];
if (loc == 0) {
proc.onMissing(docId);
return;
}
proc.onValue(docId, GeoHashUtils.encode(lat[loc], lon[loc]));

View File

@ -107,6 +107,8 @@ public class CountAndTotalHistogramFacetCollector extends AbstractFacetCollector
private final TLongDoubleHashMap totals = new TLongDoubleHashMap();
private int missing;
public HistogramProc(long interval) {
this.interval = interval;
}
@ -117,6 +119,10 @@ public class CountAndTotalHistogramFacetCollector extends AbstractFacetCollector
totals.adjustOrPutValue(bucket, value, value);
}
@Override public void onMissing(int docId) {
missing++;
}
public TLongLongHashMap counts() {
return counts;
}

View File

@ -104,6 +104,8 @@ public class CountHistogramFacetCollector extends AbstractFacetCollector {
private final TLongLongHashMap counts = new TLongLongHashMap();
private int missing;
public HistogramProc(long interval) {
this.interval = interval;
}
@ -113,6 +115,10 @@ public class CountHistogramFacetCollector extends AbstractFacetCollector {
counts.adjustOrPutValue(bucket, 1, 1);
}
@Override public void onMissing(int docId) {
missing++;
}
public TLongLongHashMap counts() {
return counts;
}

View File

@ -116,6 +116,8 @@ public class KeyValueScriptHistogramFacetCollector extends AbstractFacetCollecto
private final TLongDoubleHashMap totals = new TLongDoubleHashMap();
private int missing;
public HistogramProc(long interval, SearchScript valueScript) {
this.interval = interval;
this.valueScript = valueScript;
@ -128,6 +130,10 @@ public class KeyValueScriptHistogramFacetCollector extends AbstractFacetCollecto
totals.adjustOrPutValue(bucket, scriptValue, scriptValue);
}
@Override public void onMissing(int docId) {
missing++;
}
public TLongLongHashMap counts() {
return counts;
}

View File

@ -88,6 +88,8 @@ public class RangeFacetCollector extends AbstractFacetCollector {
private final RangeFacet.Entry[] entries;
private int missing;
public RangeProc(RangeFacet.Entry[] entries) {
this.entries = entries;
}
@ -100,5 +102,9 @@ public class RangeFacetCollector extends AbstractFacetCollector {
}
}
}
@Override public void onMissing(int docId) {
missing++;
}
}
}

View File

@ -91,6 +91,8 @@ public class StatisticalFacetCollector extends AbstractFacetCollector {
private long count;
private int missing;
@Override public void onValue(int docId, double value) {
if (value < min || Double.isNaN(min)) {
min = value;
@ -103,6 +105,10 @@ public class StatisticalFacetCollector extends AbstractFacetCollector {
count++;
}
@Override public void onMissing(int docId) {
missing++;
}
public final double min() {
return min;
}

View File

@ -97,6 +97,8 @@ public class StatisticalFieldsFacetCollector extends AbstractFacetCollector {
private long count;
private int missing;
@Override public void onValue(int docId, double value) {
if (value < min || Double.isNaN(min)) {
min = value;
@ -109,6 +111,10 @@ public class StatisticalFieldsFacetCollector extends AbstractFacetCollector {
count++;
}
@Override public void onMissing(int docId) {
missing++;
}
public final double min() {
return min;
}

View File

@ -164,6 +164,16 @@ public interface TermsFacet extends Facet, Iterable<TermsFacet.Entry> {
*/
ComparatorType getComparatorType();
/**
* The number of docs missing a value.
*/
long missingCount();
/**
* The number of docs missing a value.
*/
long getMissingCount();
/**
* The terms and counts.
*/

View File

@ -112,6 +112,8 @@ public class InternalByteTermsFacet extends InternalTermsFacet {
int requiredSize;
long missing;
Collection<ByteEntry> entries = ImmutableList.of();
private ComparatorType comparatorType;
@ -119,12 +121,13 @@ public class InternalByteTermsFacet extends InternalTermsFacet {
InternalByteTermsFacet() {
}
public InternalByteTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<ByteEntry> entries) {
public InternalByteTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<ByteEntry> entries, long missing) {
this.name = name;
this.fieldName = fieldName;
this.comparatorType = comparatorType;
this.requiredSize = requiredSize;
this.entries = entries;
this.missing = missing;
}
@Override public String name() {
@ -159,6 +162,14 @@ public class InternalByteTermsFacet extends InternalTermsFacet {
return comparatorType();
}
@Override public long missingCount() {
return this.missing;
}
@Override public long getMissingCount() {
return missingCount();
}
@Override public List<ByteEntry> entries() {
if (!(entries instanceof List)) {
entries = ImmutableList.copyOf(entries);
@ -190,8 +201,10 @@ public class InternalByteTermsFacet extends InternalTermsFacet {
TByteIntHashMap aggregated = aggregateCache.get().get();
aggregated.clear();
long missing = 0;
for (Facet facet : facets) {
InternalByteTermsFacet mFacet = (InternalByteTermsFacet) facet;
missing += mFacet.missingCount();
for (ByteEntry entry : mFacet.entries) {
aggregated.adjustOrPutValue(entry.term, entry.count(), entry.count());
}
@ -203,12 +216,14 @@ public class InternalByteTermsFacet extends InternalTermsFacet {
ordered.add(new ByteEntry(it.key(), it.value()));
}
first.entries = ordered;
first.missing = missing;
return first;
}
static final class Fields {
static final XContentBuilderString _TYPE = new XContentBuilderString("_type");
static final XContentBuilderString _FIELD = new XContentBuilderString("_field");
static final XContentBuilderString MISSING = new XContentBuilderString("missing");
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
@ -218,6 +233,7 @@ public class InternalByteTermsFacet extends InternalTermsFacet {
builder.startObject(name);
builder.field(Fields._TYPE, TermsFacet.TYPE);
builder.field(Fields._FIELD, fieldName);
builder.field(Fields.MISSING, missing);
builder.startArray(Fields.TERMS);
for (ByteEntry entry : entries) {
builder.startObject();
@ -241,6 +257,7 @@ public class InternalByteTermsFacet extends InternalTermsFacet {
fieldName = in.readUTF();
comparatorType = ComparatorType.fromId(in.readByte());
requiredSize = in.readVInt();
missing = in.readVLong();
int size = in.readVInt();
entries = new ArrayList<ByteEntry>(size);
@ -255,6 +272,7 @@ public class InternalByteTermsFacet extends InternalTermsFacet {
out.writeByte(comparatorType.id());
out.writeVInt(requiredSize);
out.writeVLong(missing);
out.writeVInt(entries.size());
for (ByteEntry entry : entries) {

View File

@ -128,7 +128,7 @@ public class TermsByteFacetCollector extends AbstractFacetCollector {
TByteIntHashMap facets = aggregator.facets();
if (facets.isEmpty()) {
pushFacets(facets);
return new InternalByteTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalByteTermsFacet.ByteEntry>of());
return new InternalByteTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalByteTermsFacet.ByteEntry>of(), aggregator.missing());
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalByteTermsFacet.ByteEntry> ordered = new BoundedTreeSet<InternalByteTermsFacet.ByteEntry>(comparatorType.comparator(), size * numberOfShards);
@ -137,7 +137,7 @@ public class TermsByteFacetCollector extends AbstractFacetCollector {
ordered.add(new InternalByteTermsFacet.ByteEntry(it.key(), it.value()));
}
pushFacets(facets);
return new InternalByteTermsFacet(facetName, fieldName, comparatorType, size, ordered);
return new InternalByteTermsFacet(facetName, fieldName, comparatorType, size, ordered, aggregator.missing());
}
}
@ -198,6 +198,8 @@ public class TermsByteFacetCollector extends AbstractFacetCollector {
private final TByteIntHashMap facets;
private int missing;
public StaticAggregatorValueProc(TByteIntHashMap facets) {
this.facets = facets;
}
@ -206,8 +208,16 @@ public class TermsByteFacetCollector extends AbstractFacetCollector {
facets.adjustOrPutValue(value, 1, 1);
}
@Override public void onMissing(int docID) {
missing++;
}
public final TByteIntHashMap facets() {
return facets;
}
public final int missing() {
return this.missing;
}
}
}

View File

@ -115,6 +115,8 @@ public class InternalDoubleTermsFacet extends InternalTermsFacet {
int requiredSize;
long missing;
Collection<DoubleEntry> entries = ImmutableList.of();
private ComparatorType comparatorType;
@ -122,12 +124,13 @@ public class InternalDoubleTermsFacet extends InternalTermsFacet {
InternalDoubleTermsFacet() {
}
public InternalDoubleTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<DoubleEntry> entries) {
public InternalDoubleTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<DoubleEntry> entries, long missing) {
this.name = name;
this.fieldName = fieldName;
this.comparatorType = comparatorType;
this.requiredSize = requiredSize;
this.entries = entries;
this.missing = missing;
}
@Override public String name() {
@ -177,6 +180,13 @@ public class InternalDoubleTermsFacet extends InternalTermsFacet {
return (Iterator) entries.iterator();
}
@Override public long missingCount() {
return this.missing;
}
@Override public long getMissingCount() {
return missingCount();
}
private static ThreadLocal<ThreadLocals.CleanableValue<TDoubleIntHashMap>> aggregateCache = new ThreadLocal<ThreadLocals.CleanableValue<TDoubleIntHashMap>>() {
@Override protected ThreadLocals.CleanableValue<TDoubleIntHashMap> initialValue() {
@ -192,9 +202,10 @@ public class InternalDoubleTermsFacet extends InternalTermsFacet {
InternalDoubleTermsFacet first = (InternalDoubleTermsFacet) facets.get(0);
TDoubleIntHashMap aggregated = aggregateCache.get().get();
aggregated.clear();
long missing = 0;
for (Facet facet : facets) {
InternalDoubleTermsFacet mFacet = (InternalDoubleTermsFacet) facet;
missing += mFacet.missingCount();
for (DoubleEntry entry : mFacet.entries) {
aggregated.adjustOrPutValue(entry.term, entry.count(), entry.count());
}
@ -206,12 +217,14 @@ public class InternalDoubleTermsFacet extends InternalTermsFacet {
ordered.add(new DoubleEntry(it.key(), it.value()));
}
first.entries = ordered;
first.missing = missing;
return first;
}
static final class Fields {
static final XContentBuilderString _TYPE = new XContentBuilderString("_type");
static final XContentBuilderString _FIELD = new XContentBuilderString("_field");
static final XContentBuilderString MISSING = new XContentBuilderString("missing");
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
@ -221,6 +234,7 @@ public class InternalDoubleTermsFacet extends InternalTermsFacet {
builder.startObject(name);
builder.field(Fields._TYPE, TermsFacet.TYPE);
builder.field(Fields._FIELD, fieldName);
builder.field(Fields.MISSING, missing);
builder.startArray(Fields.TERMS);
for (DoubleEntry entry : entries) {
builder.startObject();
@ -244,6 +258,7 @@ public class InternalDoubleTermsFacet extends InternalTermsFacet {
fieldName = in.readUTF();
comparatorType = ComparatorType.fromId(in.readByte());
requiredSize = in.readVInt();
missing = in.readVLong();
int size = in.readVInt();
entries = new ArrayList<DoubleEntry>(size);
@ -256,8 +271,8 @@ public class InternalDoubleTermsFacet extends InternalTermsFacet {
out.writeUTF(name);
out.writeUTF(fieldName);
out.writeByte(comparatorType.id());
out.writeVInt(requiredSize);
out.writeVLong(missing);
out.writeVInt(entries.size());
for (DoubleEntry entry : entries) {

View File

@ -128,7 +128,7 @@ public class TermsDoubleFacetCollector extends AbstractFacetCollector {
TDoubleIntHashMap facets = aggregator.facets();
if (facets.isEmpty()) {
pushFacets(facets);
return new InternalDoubleTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalDoubleTermsFacet.DoubleEntry>of());
return new InternalDoubleTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalDoubleTermsFacet.DoubleEntry>of(), aggregator.missing());
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalDoubleTermsFacet.DoubleEntry> ordered = new BoundedTreeSet<InternalDoubleTermsFacet.DoubleEntry>(comparatorType.comparator(), size * numberOfShards);
@ -137,7 +137,7 @@ public class TermsDoubleFacetCollector extends AbstractFacetCollector {
ordered.add(new InternalDoubleTermsFacet.DoubleEntry(it.key(), it.value()));
}
pushFacets(facets);
return new InternalDoubleTermsFacet(facetName, fieldName, comparatorType, size, ordered);
return new InternalDoubleTermsFacet(facetName, fieldName, comparatorType, size, ordered, aggregator.missing());
}
}
@ -198,6 +198,8 @@ public class TermsDoubleFacetCollector extends AbstractFacetCollector {
private final TDoubleIntHashMap facets;
private int missing;
public StaticAggregatorValueProc(TDoubleIntHashMap facets) {
this.facets = facets;
}
@ -206,8 +208,16 @@ public class TermsDoubleFacetCollector extends AbstractFacetCollector {
facets.adjustOrPutValue(value, 1, 1);
}
@Override public void onMissing(int docId) {
missing++;
}
public final TDoubleIntHashMap facets() {
return facets;
}
public final int missing() {
return this.missing;
}
}
}

View File

@ -115,6 +115,8 @@ public class InternalFloatTermsFacet extends InternalTermsFacet {
int requiredSize;
long missing;
Collection<FloatEntry> entries = ImmutableList.of();
private ComparatorType comparatorType;
@ -122,12 +124,13 @@ public class InternalFloatTermsFacet extends InternalTermsFacet {
InternalFloatTermsFacet() {
}
public InternalFloatTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<FloatEntry> entries) {
public InternalFloatTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<FloatEntry> entries, long missing) {
this.name = name;
this.fieldName = fieldName;
this.comparatorType = comparatorType;
this.requiredSize = requiredSize;
this.entries = entries;
this.missing = missing;
}
@Override public String name() {
@ -177,6 +180,13 @@ public class InternalFloatTermsFacet extends InternalTermsFacet {
return (Iterator) entries.iterator();
}
@Override public long missingCount() {
return this.missing;
}
@Override public long getMissingCount() {
return missingCount();
}
private static ThreadLocal<ThreadLocals.CleanableValue<TFloatIntHashMap>> aggregateCache = new ThreadLocal<ThreadLocals.CleanableValue<TFloatIntHashMap>>() {
@Override protected ThreadLocals.CleanableValue<TFloatIntHashMap> initialValue() {
@ -192,9 +202,11 @@ public class InternalFloatTermsFacet extends InternalTermsFacet {
InternalFloatTermsFacet first = (InternalFloatTermsFacet) facets.get(0);
TFloatIntHashMap aggregated = aggregateCache.get().get();
aggregated.clear();
long missing = 0;
for (Facet facet : facets) {
InternalFloatTermsFacet mFacet = (InternalFloatTermsFacet) facet;
missing += mFacet.missingCount();
for (FloatEntry entry : mFacet.entries) {
aggregated.adjustOrPutValue(entry.term, entry.count(), entry.count());
}
@ -206,12 +218,14 @@ public class InternalFloatTermsFacet extends InternalTermsFacet {
ordered.add(new FloatEntry(it.key(), it.value()));
}
first.entries = ordered;
first.missing = missing;
return first;
}
static final class Fields {
static final XContentBuilderString _TYPE = new XContentBuilderString("_type");
static final XContentBuilderString _FIELD = new XContentBuilderString("_field");
static final XContentBuilderString MISSING = new XContentBuilderString("missing");
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
@ -221,6 +235,7 @@ public class InternalFloatTermsFacet extends InternalTermsFacet {
builder.startObject(name);
builder.field(Fields._TYPE, TermsFacet.TYPE);
builder.field(Fields._FIELD, fieldName);
builder.field(Fields.MISSING, missing);
builder.startArray(Fields.TERMS);
for (FloatEntry entry : entries) {
builder.startObject();
@ -244,6 +259,7 @@ public class InternalFloatTermsFacet extends InternalTermsFacet {
fieldName = in.readUTF();
comparatorType = ComparatorType.fromId(in.readByte());
requiredSize = in.readVInt();
missing = in.readVLong();
int size = in.readVInt();
entries = new ArrayList<FloatEntry>(size);
@ -256,8 +272,8 @@ public class InternalFloatTermsFacet extends InternalTermsFacet {
out.writeUTF(name);
out.writeUTF(fieldName);
out.writeByte(comparatorType.id());
out.writeVInt(requiredSize);
out.writeVLong(missing);
out.writeVInt(entries.size());
for (FloatEntry entry : entries) {

View File

@ -128,7 +128,7 @@ public class TermsFloatFacetCollector extends AbstractFacetCollector {
TFloatIntHashMap facets = aggregator.facets();
if (facets.isEmpty()) {
pushFacets(facets);
return new InternalFloatTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalFloatTermsFacet.FloatEntry>of());
return new InternalFloatTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalFloatTermsFacet.FloatEntry>of(), aggregator.missing());
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalFloatTermsFacet.FloatEntry> ordered = new BoundedTreeSet<InternalFloatTermsFacet.FloatEntry>(comparatorType.comparator(), size * numberOfShards);
@ -137,7 +137,7 @@ public class TermsFloatFacetCollector extends AbstractFacetCollector {
ordered.add(new InternalFloatTermsFacet.FloatEntry(it.key(), it.value()));
}
pushFacets(facets);
return new InternalFloatTermsFacet(facetName, fieldName, comparatorType, size, ordered);
return new InternalFloatTermsFacet(facetName, fieldName, comparatorType, size, ordered, aggregator.missing());
}
}
@ -198,6 +198,8 @@ public class TermsFloatFacetCollector extends AbstractFacetCollector {
private final TFloatIntHashMap facets;
private int missing;
public StaticAggregatorValueProc(TFloatIntHashMap facets) {
this.facets = facets;
}
@ -206,8 +208,16 @@ public class TermsFloatFacetCollector extends AbstractFacetCollector {
facets.adjustOrPutValue(value, 1, 1);
}
@Override public void onMissing(int docId) {
missing++;
}
public final TFloatIntHashMap facets() {
return facets;
}
public final int missing() {
return this.missing;
}
}
}

View File

@ -56,6 +56,6 @@ public class IndexNameFacetCollector extends AbstractFacetCollector {
}
@Override public Facet facet() {
return new InternalStringTermsFacet(facetName, "_index", comparatorType, size, Sets.newHashSet(new InternalStringTermsFacet.StringEntry(indexName, count)));
return new InternalStringTermsFacet(facetName, "_index", comparatorType, size, Sets.newHashSet(new InternalStringTermsFacet.StringEntry(indexName, count)), 0);
}
}

View File

@ -112,6 +112,8 @@ public class InternalIntTermsFacet extends InternalTermsFacet {
int requiredSize;
long missing;
Collection<IntEntry> entries = ImmutableList.of();
private ComparatorType comparatorType;
@ -119,12 +121,13 @@ public class InternalIntTermsFacet extends InternalTermsFacet {
InternalIntTermsFacet() {
}
public InternalIntTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<IntEntry> entries) {
public InternalIntTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<IntEntry> entries, long missing) {
this.name = name;
this.fieldName = fieldName;
this.comparatorType = comparatorType;
this.requiredSize = requiredSize;
this.entries = entries;
this.missing = missing;
}
@Override public String name() {
@ -174,6 +177,13 @@ public class InternalIntTermsFacet extends InternalTermsFacet {
return (Iterator) entries.iterator();
}
@Override public long missingCount() {
return this.missing;
}
@Override public long getMissingCount() {
return missingCount();
}
private static ThreadLocal<ThreadLocals.CleanableValue<TIntIntHashMap>> aggregateCache = new ThreadLocal<ThreadLocals.CleanableValue<TIntIntHashMap>>() {
@Override protected ThreadLocals.CleanableValue<TIntIntHashMap> initialValue() {
@ -189,9 +199,11 @@ public class InternalIntTermsFacet extends InternalTermsFacet {
InternalIntTermsFacet first = (InternalIntTermsFacet) facets.get(0);
TIntIntHashMap aggregated = aggregateCache.get().get();
aggregated.clear();
long missing = 0;
for (Facet facet : facets) {
InternalIntTermsFacet mFacet = (InternalIntTermsFacet) facet;
missing += mFacet.missingCount();
for (IntEntry entry : mFacet.entries) {
aggregated.adjustOrPutValue(entry.term, entry.count(), entry.count());
}
@ -203,12 +215,14 @@ public class InternalIntTermsFacet extends InternalTermsFacet {
ordered.add(new IntEntry(it.key(), it.value()));
}
first.entries = ordered;
first.missing = missing;
return first;
}
static final class Fields {
static final XContentBuilderString _TYPE = new XContentBuilderString("_type");
static final XContentBuilderString _FIELD = new XContentBuilderString("_field");
static final XContentBuilderString MISSING = new XContentBuilderString("missing");
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
@ -218,6 +232,7 @@ public class InternalIntTermsFacet extends InternalTermsFacet {
builder.startObject(name);
builder.field(Fields._TYPE, TermsFacet.TYPE);
builder.field(Fields._FIELD, fieldName);
builder.field(Fields.MISSING, missing);
builder.startArray(Fields.TERMS);
for (IntEntry entry : entries) {
builder.startObject();
@ -241,6 +256,7 @@ public class InternalIntTermsFacet extends InternalTermsFacet {
fieldName = in.readUTF();
comparatorType = ComparatorType.fromId(in.readByte());
requiredSize = in.readVInt();
missing = in.readVLong();
int size = in.readVInt();
entries = new ArrayList<IntEntry>(size);
@ -253,8 +269,8 @@ public class InternalIntTermsFacet extends InternalTermsFacet {
out.writeUTF(name);
out.writeUTF(fieldName);
out.writeByte(comparatorType.id());
out.writeVInt(requiredSize);
out.writeVLong(missing);
out.writeVInt(entries.size());
for (IntEntry entry : entries) {

View File

@ -128,7 +128,7 @@ public class TermsIntFacetCollector extends AbstractFacetCollector {
TIntIntHashMap facets = aggregator.facets();
if (facets.isEmpty()) {
pushFacets(facets);
return new InternalIntTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalIntTermsFacet.IntEntry>of());
return new InternalIntTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalIntTermsFacet.IntEntry>of(), aggregator.missing());
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalIntTermsFacet.IntEntry> ordered = new BoundedTreeSet<InternalIntTermsFacet.IntEntry>(comparatorType.comparator(), size * numberOfShards);
@ -137,7 +137,7 @@ public class TermsIntFacetCollector extends AbstractFacetCollector {
ordered.add(new InternalIntTermsFacet.IntEntry(it.key(), it.value()));
}
pushFacets(facets);
return new InternalIntTermsFacet(facetName, fieldName, comparatorType, size, ordered);
return new InternalIntTermsFacet(facetName, fieldName, comparatorType, size, ordered, aggregator.missing());
}
}
@ -198,6 +198,8 @@ public class TermsIntFacetCollector extends AbstractFacetCollector {
private final TIntIntHashMap facets;
private int missing;
public StaticAggregatorValueProc(TIntIntHashMap facets) {
this.facets = facets;
}
@ -206,8 +208,16 @@ public class TermsIntFacetCollector extends AbstractFacetCollector {
facets.adjustOrPutValue(value, 1, 1);
}
@Override public void onMissing(int docId) {
missing++;
}
public final TIntIntHashMap facets() {
return facets;
}
public final int missing() {
return this.missing;
}
}
}

View File

@ -115,6 +115,8 @@ public class InternalLongTermsFacet extends InternalTermsFacet {
int requiredSize;
long missing;
Collection<LongEntry> entries = ImmutableList.of();
private ComparatorType comparatorType;
@ -122,12 +124,13 @@ public class InternalLongTermsFacet extends InternalTermsFacet {
InternalLongTermsFacet() {
}
public InternalLongTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<LongEntry> entries) {
public InternalLongTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<LongEntry> entries, long missing) {
this.name = name;
this.fieldName = fieldName;
this.comparatorType = comparatorType;
this.requiredSize = requiredSize;
this.entries = entries;
this.missing = missing;
}
@Override public String name() {
@ -177,6 +180,13 @@ public class InternalLongTermsFacet extends InternalTermsFacet {
return (Iterator) entries.iterator();
}
@Override public long missingCount() {
return this.missing;
}
@Override public long getMissingCount() {
return missingCount();
}
private static ThreadLocal<ThreadLocals.CleanableValue<TLongIntHashMap>> aggregateCache = new ThreadLocal<ThreadLocals.CleanableValue<TLongIntHashMap>>() {
@Override protected ThreadLocals.CleanableValue<TLongIntHashMap> initialValue() {
@ -192,9 +202,11 @@ public class InternalLongTermsFacet extends InternalTermsFacet {
InternalLongTermsFacet first = (InternalLongTermsFacet) facets.get(0);
TLongIntHashMap aggregated = aggregateCache.get().get();
aggregated.clear();
long missing = 0;
for (Facet facet : facets) {
InternalLongTermsFacet mFacet = (InternalLongTermsFacet) facet;
missing += mFacet.missingCount();
for (LongEntry entry : mFacet.entries) {
aggregated.adjustOrPutValue(entry.term, entry.count(), entry.count());
}
@ -206,12 +218,14 @@ public class InternalLongTermsFacet extends InternalTermsFacet {
ordered.add(new LongEntry(it.key(), it.value()));
}
first.entries = ordered;
first.missing = missing;
return first;
}
static final class Fields {
static final XContentBuilderString _TYPE = new XContentBuilderString("_type");
static final XContentBuilderString _FIELD = new XContentBuilderString("_field");
static final XContentBuilderString MISSING = new XContentBuilderString("missing");
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
@ -221,6 +235,7 @@ public class InternalLongTermsFacet extends InternalTermsFacet {
builder.startObject(name);
builder.field(Fields._TYPE, TermsFacet.TYPE);
builder.field(Fields._FIELD, fieldName);
builder.field(Fields.MISSING, missing);
builder.startArray(Fields.TERMS);
for (LongEntry entry : entries) {
builder.startObject();
@ -244,6 +259,7 @@ public class InternalLongTermsFacet extends InternalTermsFacet {
fieldName = in.readUTF();
comparatorType = ComparatorType.fromId(in.readByte());
requiredSize = in.readVInt();
missing = in.readVLong();
int size = in.readVInt();
entries = new ArrayList<LongEntry>(size);
@ -256,8 +272,8 @@ public class InternalLongTermsFacet extends InternalTermsFacet {
out.writeUTF(name);
out.writeUTF(fieldName);
out.writeByte(comparatorType.id());
out.writeVInt(requiredSize);
out.writeVLong(missing);
out.writeVInt(entries.size());
for (LongEntry entry : entries) {

View File

@ -129,7 +129,7 @@ public class TermsLongFacetCollector extends AbstractFacetCollector {
TLongIntHashMap facets = aggregator.facets();
if (facets.isEmpty()) {
pushFacets(facets);
return new InternalLongTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalLongTermsFacet.LongEntry>of());
return new InternalLongTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalLongTermsFacet.LongEntry>of(), aggregator.missing());
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalLongTermsFacet.LongEntry> ordered = new BoundedTreeSet<InternalLongTermsFacet.LongEntry>(comparatorType.comparator(), size * numberOfShards);
@ -138,7 +138,7 @@ public class TermsLongFacetCollector extends AbstractFacetCollector {
ordered.add(new InternalLongTermsFacet.LongEntry(it.key(), it.value()));
}
pushFacets(facets);
return new InternalLongTermsFacet(facetName, fieldName, comparatorType, size, ordered);
return new InternalLongTermsFacet(facetName, fieldName, comparatorType, size, ordered, aggregator.missing());
}
}
@ -199,6 +199,8 @@ public class TermsLongFacetCollector extends AbstractFacetCollector {
private final TLongIntHashMap facets;
private int missing;
public StaticAggregatorValueProc(TLongIntHashMap facets) {
this.facets = facets;
}
@ -207,8 +209,16 @@ public class TermsLongFacetCollector extends AbstractFacetCollector {
facets.adjustOrPutValue(value, 1, 1);
}
@Override public void onMissing(int docId) {
missing++;
}
public final TLongIntHashMap facets() {
return facets;
}
public final int missing() {
return this.missing;
}
}
}

View File

@ -112,6 +112,8 @@ public class InternalShortTermsFacet extends InternalTermsFacet {
int requiredSize;
long missing;
Collection<ShortEntry> entries = ImmutableList.of();
private ComparatorType comparatorType;
@ -119,12 +121,13 @@ public class InternalShortTermsFacet extends InternalTermsFacet {
InternalShortTermsFacet() {
}
public InternalShortTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<ShortEntry> entries) {
public InternalShortTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<ShortEntry> entries, long missing) {
this.name = name;
this.fieldName = fieldName;
this.comparatorType = comparatorType;
this.requiredSize = requiredSize;
this.entries = entries;
this.missing = missing;
}
@Override public String name() {
@ -174,6 +177,13 @@ public class InternalShortTermsFacet extends InternalTermsFacet {
return (Iterator) entries.iterator();
}
@Override public long missingCount() {
return this.missing;
}
@Override public long getMissingCount() {
return missingCount();
}
private static ThreadLocal<ThreadLocals.CleanableValue<TShortIntHashMap>> aggregateCache = new ThreadLocal<ThreadLocals.CleanableValue<TShortIntHashMap>>() {
@Override protected ThreadLocals.CleanableValue<TShortIntHashMap> initialValue() {
@ -189,9 +199,10 @@ public class InternalShortTermsFacet extends InternalTermsFacet {
InternalShortTermsFacet first = (InternalShortTermsFacet) facets.get(0);
TShortIntHashMap aggregated = aggregateCache.get().get();
aggregated.clear();
long missing = 0;
for (Facet facet : facets) {
InternalShortTermsFacet mFacet = (InternalShortTermsFacet) facet;
missing += mFacet.missingCount();
for (ShortEntry entry : mFacet.entries) {
aggregated.adjustOrPutValue(entry.term, entry.count(), entry.count());
}
@ -203,12 +214,14 @@ public class InternalShortTermsFacet extends InternalTermsFacet {
ordered.add(new ShortEntry(it.key(), it.value()));
}
first.entries = ordered;
first.missing = missing;
return first;
}
static final class Fields {
static final XContentBuilderString _TYPE = new XContentBuilderString("_type");
static final XContentBuilderString _FIELD = new XContentBuilderString("_field");
static final XContentBuilderString MISSING = new XContentBuilderString("missing");
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
@ -218,6 +231,7 @@ public class InternalShortTermsFacet extends InternalTermsFacet {
builder.startObject(name);
builder.field(Fields._TYPE, TermsFacet.TYPE);
builder.field(Fields._FIELD, fieldName);
builder.field(Fields.MISSING, missing);
builder.startArray(Fields.TERMS);
for (ShortEntry entry : entries) {
builder.startObject();
@ -241,6 +255,7 @@ public class InternalShortTermsFacet extends InternalTermsFacet {
fieldName = in.readUTF();
comparatorType = ComparatorType.fromId(in.readByte());
requiredSize = in.readVInt();
missing = in.readVLong();
int size = in.readVInt();
entries = new ArrayList<ShortEntry>(size);
@ -253,8 +268,8 @@ public class InternalShortTermsFacet extends InternalTermsFacet {
out.writeUTF(name);
out.writeUTF(fieldName);
out.writeByte(comparatorType.id());
out.writeVInt(requiredSize);
out.writeVLong(missing);
out.writeVInt(entries.size());
for (ShortEntry entry : entries) {

View File

@ -128,7 +128,7 @@ public class TermsShortFacetCollector extends AbstractFacetCollector {
TShortIntHashMap facets = aggregator.facets();
if (facets.isEmpty()) {
pushFacets(facets);
return new InternalShortTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalShortTermsFacet.ShortEntry>of());
return new InternalShortTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalShortTermsFacet.ShortEntry>of(), aggregator.missing());
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalShortTermsFacet.ShortEntry> ordered = new BoundedTreeSet<InternalShortTermsFacet.ShortEntry>(comparatorType.comparator(), size * numberOfShards);
@ -137,7 +137,7 @@ public class TermsShortFacetCollector extends AbstractFacetCollector {
ordered.add(new InternalShortTermsFacet.ShortEntry(it.key(), it.value()));
}
pushFacets(facets);
return new InternalShortTermsFacet(facetName, fieldName, comparatorType, size, ordered);
return new InternalShortTermsFacet(facetName, fieldName, comparatorType, size, ordered, aggregator.missing());
}
}
@ -198,6 +198,8 @@ public class TermsShortFacetCollector extends AbstractFacetCollector {
private final TShortIntHashMap facets;
private int missing;
public StaticAggregatorValueProc(TShortIntHashMap facets) {
this.facets = facets;
}
@ -206,8 +208,16 @@ public class TermsShortFacetCollector extends AbstractFacetCollector {
facets.adjustOrPutValue(value, 1, 1);
}
@Override public void onMissing(int docId) {
missing++;
}
public final TShortIntHashMap facets() {
return facets;
}
public final int missing() {
return this.missing;
}
}
}

View File

@ -125,7 +125,7 @@ public class FieldsTermsStringFacetCollector extends AbstractFacetCollector {
TObjectIntHashMap<String> facets = aggregator.facets();
if (facets.isEmpty()) {
TermsStringFacetCollector.pushFacets(facets);
return new InternalStringTermsFacet(facetName, arrayToCommaDelimitedString(fieldsNames), comparatorType, size, ImmutableList.<InternalStringTermsFacet.StringEntry>of());
return new InternalStringTermsFacet(facetName, arrayToCommaDelimitedString(fieldsNames), comparatorType, size, ImmutableList.<InternalStringTermsFacet.StringEntry>of(), aggregator.missing());
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalStringTermsFacet.StringEntry> ordered = new BoundedTreeSet<InternalStringTermsFacet.StringEntry>(comparatorType.comparator(), size * numberOfShards);
@ -134,7 +134,7 @@ public class FieldsTermsStringFacetCollector extends AbstractFacetCollector {
ordered.add(new InternalStringTermsFacet.StringEntry(it.key(), it.value()));
}
TermsStringFacetCollector.pushFacets(facets);
return new InternalStringTermsFacet(facetName, arrayToCommaDelimitedString(fieldsNames), comparatorType, size, ordered);
return new InternalStringTermsFacet(facetName, arrayToCommaDelimitedString(fieldsNames), comparatorType, size, ordered, aggregator.missing());
}
}
@ -189,6 +189,8 @@ public class FieldsTermsStringFacetCollector extends AbstractFacetCollector {
private final TObjectIntHashMap<String> facets;
private int missing;
public StaticAggregatorValueProc(TObjectIntHashMap<String> facets) {
this.facets = facets;
}
@ -197,8 +199,16 @@ public class FieldsTermsStringFacetCollector extends AbstractFacetCollector {
facets.adjustOrPutValue(value, 1, 1);
}
@Override public void onMissing(int docId) {
missing++;
}
public final TObjectIntHashMap<String> facets() {
return facets;
}
public final int missing() {
return this.missing;
}
}
}

View File

@ -111,6 +111,8 @@ public class InternalStringTermsFacet extends InternalTermsFacet {
int requiredSize;
long missing;
Collection<StringEntry> entries = ImmutableList.of();
private ComparatorType comparatorType;
@ -118,12 +120,13 @@ public class InternalStringTermsFacet extends InternalTermsFacet {
InternalStringTermsFacet() {
}
public InternalStringTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<StringEntry> entries) {
public InternalStringTermsFacet(String name, String fieldName, ComparatorType comparatorType, int requiredSize, Collection<StringEntry> entries, long missing) {
this.name = name;
this.fieldName = fieldName;
this.comparatorType = comparatorType;
this.requiredSize = requiredSize;
this.entries = entries;
this.missing = missing;
}
@Override public String name() {
@ -173,6 +176,13 @@ public class InternalStringTermsFacet extends InternalTermsFacet {
return (Iterator) entries.iterator();
}
@Override public long missingCount() {
return this.missing;
}
@Override public long getMissingCount() {
return missingCount();
}
private static ThreadLocal<ThreadLocals.CleanableValue<TObjectIntHashMap<String>>> aggregateCache = new ThreadLocal<ThreadLocals.CleanableValue<TObjectIntHashMap<String>>>() {
@Override protected ThreadLocals.CleanableValue<TObjectIntHashMap<String>> initialValue() {
@ -188,9 +198,10 @@ public class InternalStringTermsFacet extends InternalTermsFacet {
InternalStringTermsFacet first = (InternalStringTermsFacet) facets.get(0);
TObjectIntHashMap<String> aggregated = aggregateCache.get().get();
aggregated.clear();
long missing = 0;
for (Facet facet : facets) {
InternalStringTermsFacet mFacet = (InternalStringTermsFacet) facet;
missing += mFacet.missingCount();
for (InternalStringTermsFacet.StringEntry entry : mFacet.entries) {
aggregated.adjustOrPutValue(entry.term(), entry.count(), entry.count());
}
@ -202,12 +213,14 @@ public class InternalStringTermsFacet extends InternalTermsFacet {
ordered.add(new StringEntry(it.key(), it.value()));
}
first.entries = ordered;
first.missing = missing;
return first;
}
static final class Fields {
static final XContentBuilderString _TYPE = new XContentBuilderString("_type");
static final XContentBuilderString _FIELD = new XContentBuilderString("_field");
static final XContentBuilderString MISSING = new XContentBuilderString("missing");
static final XContentBuilderString TERMS = new XContentBuilderString("terms");
static final XContentBuilderString TERM = new XContentBuilderString("term");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
@ -217,6 +230,7 @@ public class InternalStringTermsFacet extends InternalTermsFacet {
builder.startObject(name);
builder.field(Fields._TYPE, TermsFacet.TYPE);
builder.field(Fields._FIELD, fieldName);
builder.field(Fields.MISSING, missing);
builder.startArray(Fields.TERMS);
for (Entry entry : entries) {
builder.startObject();
@ -240,6 +254,7 @@ public class InternalStringTermsFacet extends InternalTermsFacet {
fieldName = in.readUTF();
comparatorType = ComparatorType.fromId(in.readByte());
requiredSize = in.readVInt();
missing = in.readVLong();
int size = in.readVInt();
entries = new ArrayList<StringEntry>(size);
@ -252,8 +267,8 @@ public class InternalStringTermsFacet extends InternalTermsFacet {
out.writeUTF(name);
out.writeUTF(fieldName);
out.writeByte(comparatorType.id());
out.writeVInt(requiredSize);
out.writeVLong(missing);
out.writeVInt(entries.size());
for (Entry entry : entries) {

View File

@ -56,6 +56,8 @@ public class ScriptTermsStringFieldFacetCollector extends AbstractFacetCollector
private final TObjectIntHashMap<String> facets;
private int missing;
public ScriptTermsStringFieldFacetCollector(String facetName, int size, InternalStringTermsFacet.ComparatorType comparatorType, SearchContext context,
ImmutableSet<String> excluded, Pattern pattern, String scriptLang, String script, Map<String, Object> params) {
super(facetName);
@ -78,26 +80,39 @@ public class ScriptTermsStringFieldFacetCollector extends AbstractFacetCollector
@Override protected void doCollect(int doc) throws IOException {
Object o = script.execute(doc);
if (o == null) {
missing++;
return;
}
if (o instanceof Iterable) {
boolean found = false;
for (Object o1 : ((Iterable) o)) {
String value = o1.toString();
if (match(value)) {
found = true;
facets.adjustOrPutValue(value, 1, 1);
}
}
if (!found) {
missing++;
}
} else if (o instanceof Object[]) {
boolean found = false;
for (Object o1 : ((Object[]) o)) {
String value = o1.toString();
if (match(value)) {
found = true;
facets.adjustOrPutValue(value, 1, 1);
}
}
if (!found) {
missing++;
}
} else {
String value = o.toString();
if (match(value)) {
facets.adjustOrPutValue(value, 1, 1);
} else {
missing++;
}
}
}
@ -115,7 +130,7 @@ public class ScriptTermsStringFieldFacetCollector extends AbstractFacetCollector
@Override public Facet facet() {
if (facets.isEmpty()) {
TermsStringFacetCollector.pushFacets(facets);
return new InternalStringTermsFacet(facetName, sScript, comparatorType, size, ImmutableList.<InternalStringTermsFacet.StringEntry>of());
return new InternalStringTermsFacet(facetName, sScript, comparatorType, size, ImmutableList.<InternalStringTermsFacet.StringEntry>of(), missing);
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalStringTermsFacet.StringEntry> ordered = new BoundedTreeSet<InternalStringTermsFacet.StringEntry>(comparatorType.comparator(), size * numberOfShards);
@ -124,7 +139,7 @@ public class ScriptTermsStringFieldFacetCollector extends AbstractFacetCollector
ordered.add(new InternalStringTermsFacet.StringEntry(it.key(), it.value()));
}
TermsStringFacetCollector.pushFacets(facets);
return new InternalStringTermsFacet(facetName, sScript, comparatorType, size, ordered);
return new InternalStringTermsFacet(facetName, sScript, comparatorType, size, ordered, missing);
}
}
}

View File

@ -128,7 +128,7 @@ public class TermsStringFacetCollector extends AbstractFacetCollector {
TObjectIntHashMap<String> facets = aggregator.facets();
if (facets.isEmpty()) {
pushFacets(facets);
return new InternalStringTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalStringTermsFacet.StringEntry>of());
return new InternalStringTermsFacet(facetName, fieldName, comparatorType, size, ImmutableList.<InternalStringTermsFacet.StringEntry>of(), aggregator.missing());
} else {
// we need to fetch facets of "size * numberOfShards" because of problems in how they are distributed across shards
BoundedTreeSet<InternalStringTermsFacet.StringEntry> ordered = new BoundedTreeSet<InternalStringTermsFacet.StringEntry>(comparatorType.comparator(), size * numberOfShards);
@ -137,7 +137,7 @@ public class TermsStringFacetCollector extends AbstractFacetCollector {
ordered.add(new InternalStringTermsFacet.StringEntry(it.key(), it.value()));
}
pushFacets(facets);
return new InternalStringTermsFacet(facetName, fieldName, comparatorType, size, ordered);
return new InternalStringTermsFacet(facetName, fieldName, comparatorType, size, ordered, aggregator.missing());
}
}
@ -210,6 +210,8 @@ public class TermsStringFacetCollector extends AbstractFacetCollector {
private final TObjectIntHashMap<String> facets;
private int missing = 0;
public StaticAggregatorValueProc(TObjectIntHashMap<String> facets) {
this.facets = facets;
}
@ -218,8 +220,16 @@ public class TermsStringFacetCollector extends AbstractFacetCollector {
facets.adjustOrPutValue(value, 1, 1);
}
@Override public void onMissing(int docId) {
missing++;
}
public final TObjectIntHashMap<String> facets() {
return facets;
}
public final int missing() {
return this.missing;
}
}
}

View File

@ -208,6 +208,47 @@ public class SimpleFacetsTests extends AbstractNodesTests {
assertThat(facet.count(), equalTo(2l));
}
@Test public void testTermsFacetsMissing() throws Exception {
try {
client.admin().indices().prepareDelete("test").execute().actionGet();
} catch (Exception e) {
// ignore
}
client.admin().indices().prepareCreate("test")
.addMapping("type1", jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("bstag").field("type", "byte").endObject()
.startObject("shstag").field("type", "short").endObject()
.startObject("istag").field("type", "integer").endObject()
.startObject("lstag").field("type", "long").endObject()
.startObject("fstag").field("type", "float").endObject()
.startObject("dstag").field("type", "double").endObject()
.endObject().endObject().endObject())
.execute().actionGet();
client.admin().cluster().prepareHealth().setWaitForGreenStatus().execute().actionGet();
client.prepareIndex("test", "type1").setSource(jsonBuilder().startObject()
.field("stag", "111")
.field("bstag", 111)
.field("shstag", 111)
.field("istag", 111)
.field("lstag", 111)
.field("fstag", 111.1f)
.field("dstag", 111.1)
.endObject()).execute().actionGet();
client.prepareIndex("test", "type1").setSource(jsonBuilder().startObject()
.field("kuku", "kuku")
.endObject()).execute().actionGet();
client.admin().indices().prepareFlush().setRefresh(true).execute().actionGet();
SearchResponse searchResponse = client.prepareSearch()
.setQuery(matchAllQuery())
.addFacet(termsFacet("facet1").field("stag").size(10))
.execute().actionGet();
TermsFacet facet = searchResponse.facets().facet("facet1");
assertThat(facet.missingCount(), equalTo(1l));
}
@Test public void testTermsFacets() throws Exception {
try {
client.admin().indices().prepareDelete("test").execute().actionGet();