parent
16431a6601
commit
100e3c9a8a
|
@ -43,8 +43,9 @@ import org.elasticsearch.index.fielddata.IndexNumericFieldData;
|
||||||
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
||||||
import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
||||||
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
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.DateFieldMapper;
|
||||||
|
import org.elasticsearch.index.mapper.GeoPointFieldMapper.GeoPointFieldType;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.NumberFieldMapper;
|
import org.elasticsearch.index.mapper.NumberFieldMapper;
|
||||||
import org.elasticsearch.index.query.QueryShardContext;
|
import org.elasticsearch.index.query.QueryShardContext;
|
||||||
|
@ -346,22 +347,23 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
|
||||||
@Override
|
@Override
|
||||||
protected NumericDoubleValues distance(LeafReaderContext context) {
|
protected NumericDoubleValues distance(LeafReaderContext context) {
|
||||||
final MultiGeoPointValues geoPointValues = fieldData.load(context).getGeoPointValues();
|
final MultiGeoPointValues geoPointValues = fieldData.load(context).getGeoPointValues();
|
||||||
return mode.select(new MultiValueMode.UnsortedNumericDoubleValues() {
|
return mode.select(new SortingNumericDoubleValues() {
|
||||||
@Override
|
|
||||||
public int docValueCount() {
|
|
||||||
return geoPointValues.docValueCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean advanceExact(int docId) throws IOException {
|
public boolean advanceExact(int docId) throws IOException {
|
||||||
return geoPointValues.advanceExact(docId);
|
if (geoPointValues.advanceExact(docId)) {
|
||||||
}
|
int n = geoPointValues.docValueCount();
|
||||||
|
resize(n);
|
||||||
@Override
|
for (int i = 0; i < n; i++) {
|
||||||
public double nextValue() throws IOException {
|
GeoPoint other = geoPointValues.nextValue();
|
||||||
GeoPoint other = geoPointValues.nextValue();
|
double distance = distFunction.calculate(
|
||||||
return Math.max(0.0d,
|
origin.lat(), origin.lon(), other.lat(), other.lon(), DistanceUnit.METERS);
|
||||||
distFunction.calculate(origin.lat(), origin.lon(), other.lat(), other.lon(), DistanceUnit.METERS) - offset);
|
values[i] = Math.max(0.0d, distance - offset);
|
||||||
|
}
|
||||||
|
sort();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, 0.0);
|
}, 0.0);
|
||||||
}
|
}
|
||||||
|
@ -427,20 +429,20 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
|
||||||
@Override
|
@Override
|
||||||
protected NumericDoubleValues distance(LeafReaderContext context) {
|
protected NumericDoubleValues distance(LeafReaderContext context) {
|
||||||
final SortedNumericDoubleValues doubleValues = fieldData.load(context).getDoubleValues();
|
final SortedNumericDoubleValues doubleValues = fieldData.load(context).getDoubleValues();
|
||||||
return mode.select(new MultiValueMode.UnsortedNumericDoubleValues() {
|
return mode.select(new SortingNumericDoubleValues() {
|
||||||
@Override
|
@Override
|
||||||
public int docValueCount() {
|
public boolean advanceExact(int docId) throws IOException {
|
||||||
return doubleValues.docValueCount();
|
if (doubleValues.advanceExact(docId)) {
|
||||||
}
|
int n = doubleValues.docValueCount();
|
||||||
|
resize(n);
|
||||||
@Override
|
for (int i = 0; i < n; i++) {
|
||||||
public boolean advanceExact(int doc) throws IOException {
|
values[i] = Math.max(0.0d, Math.abs(doubleValues.nextValue() - origin) - offset);
|
||||||
return doubleValues.advanceExact(doc);
|
}
|
||||||
}
|
sort();
|
||||||
|
return true;
|
||||||
@Override
|
} else {
|
||||||
public double nextValue() throws IOException {
|
return false;
|
||||||
return Math.max(0.0d, Math.abs(doubleValues.nextValue() - origin) - offset);
|
}
|
||||||
}
|
}
|
||||||
}, 0.0);
|
}, 0.0);
|
||||||
}
|
}
|
||||||
|
@ -542,10 +544,11 @@ public abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
|
||||||
if (distance.advanceExact(docId) == false) {
|
if (distance.advanceExact(docId) == false) {
|
||||||
return Explanation.noMatch("No value for the distance");
|
return Explanation.noMatch("No value for the distance");
|
||||||
}
|
}
|
||||||
|
double value = distance.doubleValue();
|
||||||
return Explanation.match(
|
return Explanation.match(
|
||||||
(float) score(docId, subQueryScore.getValue()),
|
(float) score(docId, subQueryScore.getValue()),
|
||||||
"Function for field " + getFieldName() + ":",
|
"Function for field " + getFieldName() + ":",
|
||||||
func.explainFunction(getDistanceString(ctx, docId), distance.doubleValue(), scale));
|
func.explainFunction(getDistanceString(ctx, docId), value, scale));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,16 +104,6 @@ public enum MultiValueMode implements Writeable {
|
||||||
}
|
}
|
||||||
return totalCount > 0 ? totalValue : missingValue;
|
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 @@ public enum MultiValueMode implements Writeable {
|
||||||
}
|
}
|
||||||
return totalValue/totalCount;
|
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 @@ public enum MultiValueMode implements Writeable {
|
||||||
}
|
}
|
||||||
return hasValue ? ord : -1;
|
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 @@ public enum MultiValueMode implements Writeable {
|
||||||
}
|
}
|
||||||
return ord;
|
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 @@ public enum MultiValueMode implements Writeable {
|
||||||
throw new IllegalArgumentException("Unsupported sort mode: " + this);
|
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,
|
|
||||||
* <code>missingValue</code> 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
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
out.writeEnum(this);
|
out.writeEnum(this);
|
||||||
|
|
|
@ -41,7 +41,6 @@ import org.elasticsearch.index.fielddata.FieldData;
|
||||||
import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
||||||
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
|
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
|
||||||
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
||||||
import org.elasticsearch.search.MultiValueMode.UnsortedNumericDoubleValues;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -92,7 +91,7 @@ public class MultiValueModeTests extends ESTestCase {
|
||||||
docsWithValue.set(i);
|
docsWithValue.set(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Supplier<SortedNumericDocValues> multiValues = () -> DocValues.singleton(new AbstractNumericDocValues() {
|
final Supplier<SortedNumericDocValues> multiValues = () -> DocValues.singleton(new AbstractNumericDocValues() {
|
||||||
int docId = -1;
|
int docId = -1;
|
||||||
@Override
|
@Override
|
||||||
|
@ -711,126 +710,6 @@ public class MultiValueModeTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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<MultiValueMode.UnsortedNumericDoubleValues> 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() {
|
public void testValidOrdinals() {
|
||||||
assertThat(MultiValueMode.SUM.ordinal(), equalTo(0));
|
assertThat(MultiValueMode.SUM.ordinal(), equalTo(0));
|
||||||
assertThat(MultiValueMode.AVG.ordinal(), equalTo(1));
|
assertThat(MultiValueMode.AVG.ordinal(), equalTo(1));
|
||||||
|
|
Loading…
Reference in New Issue