diff --git a/core/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionBuilder.java b/core/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionBuilder.java
index dcd1399bf5159..fe7d097638f31 100644
--- a/core/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionBuilder.java
+++ b/core/src/main/java/org/elasticsearch/index/query/functionscore/DecayFunctionBuilder.java
@@ -43,8 +43,9 @@
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
import org.elasticsearch.index.fielddata.NumericDoubleValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
-import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
+import org.elasticsearch.index.fielddata.SortingNumericDoubleValues;
import org.elasticsearch.index.mapper.DateFieldMapper;
+import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.NumberFieldMapper;
import org.elasticsearch.index.query.QueryShardContext;
@@ -346,22 +347,23 @@ public boolean needsScores() {
@Override
protected NumericDoubleValues distance(LeafReaderContext context) {
final MultiGeoPointValues geoPointValues = fieldData.load(context).getGeoPointValues();
- return mode.select(new MultiValueMode.UnsortedNumericDoubleValues() {
- @Override
- public int docValueCount() {
- return geoPointValues.docValueCount();
- }
-
+ return mode.select(new SortingNumericDoubleValues() {
@Override
public boolean advanceExact(int docId) throws IOException {
- return geoPointValues.advanceExact(docId);
- }
-
- @Override
- public double nextValue() throws IOException {
- GeoPoint other = geoPointValues.nextValue();
- return Math.max(0.0d,
- distFunction.calculate(origin.lat(), origin.lon(), other.lat(), other.lon(), DistanceUnit.METERS) - offset);
+ if (geoPointValues.advanceExact(docId)) {
+ int n = geoPointValues.docValueCount();
+ resize(n);
+ for (int i = 0; i < n; i++) {
+ GeoPoint other = geoPointValues.nextValue();
+ double distance = distFunction.calculate(
+ origin.lat(), origin.lon(), other.lat(), other.lon(), DistanceUnit.METERS);
+ values[i] = Math.max(0.0d, distance - offset);
+ }
+ sort();
+ return true;
+ } else {
+ return false;
+ }
}
}, 0.0);
}
@@ -427,20 +429,20 @@ public boolean needsScores() {
@Override
protected NumericDoubleValues distance(LeafReaderContext context) {
final SortedNumericDoubleValues doubleValues = fieldData.load(context).getDoubleValues();
- return mode.select(new MultiValueMode.UnsortedNumericDoubleValues() {
+ return mode.select(new SortingNumericDoubleValues() {
@Override
- public int docValueCount() {
- return doubleValues.docValueCount();
- }
-
- @Override
- public boolean advanceExact(int doc) throws IOException {
- return doubleValues.advanceExact(doc);
- }
-
- @Override
- public double nextValue() throws IOException {
- return Math.max(0.0d, Math.abs(doubleValues.nextValue() - origin) - offset);
+ public boolean advanceExact(int docId) throws IOException {
+ if (doubleValues.advanceExact(docId)) {
+ int n = doubleValues.docValueCount();
+ resize(n);
+ for (int i = 0; i < n; i++) {
+ values[i] = Math.max(0.0d, Math.abs(doubleValues.nextValue() - origin) - offset);
+ }
+ sort();
+ return true;
+ } else {
+ return false;
+ }
}
}, 0.0);
}
@@ -542,10 +544,11 @@ public Explanation explainScore(int docId, Explanation subQueryScore) throws IOE
if (distance.advanceExact(docId) == false) {
return Explanation.noMatch("No value for the distance");
}
+ double value = distance.doubleValue();
return Explanation.match(
(float) score(docId, subQueryScore.getValue()),
"Function for field " + getFieldName() + ":",
- func.explainFunction(getDistanceString(ctx, docId), distance.doubleValue(), scale));
+ func.explainFunction(getDistanceString(ctx, docId), value, scale));
}
};
}
diff --git a/core/src/main/java/org/elasticsearch/search/MultiValueMode.java b/core/src/main/java/org/elasticsearch/search/MultiValueMode.java
index 1195644e328a0..2d85c379f54fd 100644
--- a/core/src/main/java/org/elasticsearch/search/MultiValueMode.java
+++ b/core/src/main/java/org/elasticsearch/search/MultiValueMode.java
@@ -104,16 +104,6 @@ protected double pick(SortedNumericDoubleValues values, double missingValue, Doc
}
return totalCount > 0 ? totalValue : missingValue;
}
-
- @Override
- protected double pick(UnsortedNumericDoubleValues values) throws IOException {
- final int count = values.docValueCount();
- double total = 0;
- for (int index = 0; index < count; ++index) {
- total += values.nextValue();
- }
- return total;
- }
},
/**
@@ -177,16 +167,6 @@ protected double pick(SortedNumericDoubleValues values, double missingValue, Doc
}
return totalValue/totalCount;
}
-
- @Override
- protected double pick(UnsortedNumericDoubleValues values) throws IOException {
- final int count = values.docValueCount();
- double total = 0;
- for (int index = 0; index < count; ++index) {
- total += values.nextValue();
- }
- return total/count;
- }
},
/**
@@ -303,16 +283,6 @@ protected int pick(SortedDocValues values, DocIdSetIterator docItr, int startDoc
}
return hasValue ? ord : -1;
}
-
- @Override
- protected double pick(UnsortedNumericDoubleValues values) throws IOException {
- int count = values.docValueCount();
- double min = Double.POSITIVE_INFINITY;
- for (int index = 0; index < count; ++index) {
- min = Math.min(values.nextValue(), min);
- }
- return min;
- }
},
/**
@@ -419,16 +389,6 @@ protected int pick(SortedDocValues values, DocIdSetIterator docItr, int startDoc
}
return ord;
}
-
- @Override
- protected double pick(UnsortedNumericDoubleValues values) throws IOException {
- int count = values.docValueCount();
- double max = Double.NEGATIVE_INFINITY;
- for (int index = 0; index < count; ++index) {
- max = Math.max(values.nextValue(), max);
- }
- return max;
- }
};
/**
@@ -905,43 +865,6 @@ protected int pick(SortedDocValues values, DocIdSetIterator docItr, int startDoc
throw new IllegalArgumentException("Unsupported sort mode: " + this);
}
- /**
- * Return a {@link NumericDoubleValues} instance that can be used to sort documents
- * with this mode and the provided values. When a document has no value,
- * missingValue
is returned.
- *
- * Allowed Modes: SUM, AVG, MIN, MAX
- */
- public NumericDoubleValues select(final UnsortedNumericDoubleValues values, final double missingValue) {
- return new NumericDoubleValues() {
- private boolean hasValue;
-
- @Override
- public boolean advanceExact(int doc) throws IOException {
- hasValue = values.advanceExact(doc);
- return true;
- }
- @Override
- public double doubleValue() throws IOException {
- return hasValue ? pick(values) : missingValue;
- }
- };
- }
-
- protected double pick(UnsortedNumericDoubleValues values) throws IOException {
- throw new IllegalArgumentException("Unsupported sort mode: " + this);
- }
-
- /**
- * Interface allowing custom value generators to be used in MultiValueMode.
- */
- // TODO: why do we need it???
- public interface UnsortedNumericDoubleValues {
- boolean advanceExact(int doc) throws IOException;
- int docValueCount() throws IOException;
- double nextValue() throws IOException;
- }
-
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeEnum(this);
diff --git a/core/src/test/java/org/elasticsearch/search/MultiValueModeTests.java b/core/src/test/java/org/elasticsearch/search/MultiValueModeTests.java
index 1a357c55eb056..df18b00528c66 100644
--- a/core/src/test/java/org/elasticsearch/search/MultiValueModeTests.java
+++ b/core/src/test/java/org/elasticsearch/search/MultiValueModeTests.java
@@ -41,7 +41,6 @@
import org.elasticsearch.index.fielddata.NumericDoubleValues;
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
-import org.elasticsearch.search.MultiValueMode.UnsortedNumericDoubleValues;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
@@ -92,7 +91,7 @@ public void testSingleValuedLongs() throws Exception {
docsWithValue.set(i);
}
}
-
+
final Supplier multiValues = () -> DocValues.singleton(new AbstractNumericDocValues() {
int docId = -1;
@Override
@@ -711,126 +710,6 @@ private void verifySortedSet(Supplier supplier, int maxDoc,
}
}
- public void testUnsortedSingleValuedDoubles() throws Exception {
- final int numDocs = scaledRandomIntBetween(1, 100);
- final double[] array = new double[numDocs];
- final FixedBitSet docsWithValue = randomBoolean() ? null : new FixedBitSet(numDocs);
- for (int i = 0; i < array.length; ++i) {
- if (randomBoolean()) {
- array[i] = randomDouble();
- if (docsWithValue != null) {
- docsWithValue.set(i);
- }
- } else if (docsWithValue != null && randomBoolean()) {
- docsWithValue.set(i);
- }
- }
- final NumericDoubleValues singleValues = new NumericDoubleValues() {
- private int docID;
- @Override
- public boolean advanceExact(int doc) throws IOException {
- docID = doc;
- return docsWithValue == null || docsWithValue.get(docID);
- }
- @Override
- public double doubleValue() {
- return array[docID];
- }
- };
- final SortedNumericDoubleValues singletonValues = FieldData.singleton(singleValues);
- final MultiValueMode.UnsortedNumericDoubleValues multiValues = new MultiValueMode.UnsortedNumericDoubleValues() {
-
- @Override
- public int docValueCount() {
- return singletonValues.docValueCount();
- }
-
- @Override
- public boolean advanceExact(int doc) throws IOException {
- return singletonValues.advanceExact(doc);
- }
-
- @Override
- public double nextValue() throws IOException {
- return Math.cos(singletonValues.nextValue());
- }
- };
- verifyUnsortedNumeric(() -> multiValues, numDocs);
- }
-
- public void testUnsortedMultiValuedDoubles() throws Exception {
- final int numDocs = scaledRandomIntBetween(1, 100);
- final double[][] array = new double[numDocs][];
- for (int i = 0; i < numDocs; ++i) {
- final double[] values = new double[randomInt(4)];
- for (int j = 0; j < values.length; ++j) {
- values[j] = randomDouble();
- }
- Arrays.sort(values);
- array[i] = values;
- }
- final MultiValueMode.UnsortedNumericDoubleValues multiValues = new MultiValueMode.UnsortedNumericDoubleValues() {
- int doc;
- int i;
-
- @Override
- public int docValueCount() {
- return array[doc].length;
- }
-
- @Override
- public boolean advanceExact(int doc) {
- this.doc = doc;
- i = 0;
- return array[doc].length > 0;
- }
-
- @Override
- public double nextValue() {
- return Math.sin(array[doc][i++]);
- }
- };
- verifyUnsortedNumeric(() -> multiValues, numDocs);
- }
-
- private void verifyUnsortedNumeric(Supplier supplier, int maxDoc) throws IOException {
- for (double missingValue : new double[] { 0, randomDouble() }) {
- for (MultiValueMode mode : new MultiValueMode[] {MultiValueMode.MIN, MultiValueMode.MAX, MultiValueMode.SUM, MultiValueMode.AVG}) {
- UnsortedNumericDoubleValues values = supplier.get();
- final NumericDoubleValues selected = mode.select(values, missingValue);
- for (int i = 0; i < maxDoc; ++i) {
- assertTrue(selected.advanceExact(i));
- final double actual = selected.doubleValue();
- double expected = 0.0;
- if (values.advanceExact(i) == false) {
- expected = missingValue;
- } else {
- int numValues = values.docValueCount();
- if (mode == MultiValueMode.MAX) {
- expected = Long.MIN_VALUE;
- } else if (mode == MultiValueMode.MIN) {
- expected = Long.MAX_VALUE;
- }
- for (int j = 0; j < numValues; ++j) {
- if (mode == MultiValueMode.SUM || mode == MultiValueMode.AVG) {
- expected += values.nextValue();
- } else if (mode == MultiValueMode.MIN) {
- expected = Math.min(expected, values.nextValue());
- } else if (mode == MultiValueMode.MAX) {
- expected = Math.max(expected, values.nextValue());
- }
- }
- if (mode == MultiValueMode.AVG) {
- expected = expected/numValues;
- }
- }
-
- assertEquals(mode.toString() + " docId=" + i, expected, actual, 0.1);
- }
- }
- }
- }
-
public void testValidOrdinals() {
assertThat(MultiValueMode.SUM.ordinal(), equalTo(0));
assertThat(MultiValueMode.AVG.ordinal(), equalTo(1));