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.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 abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
|
|||
@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 abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
|
|||
@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 abstract class DecayFunctionBuilder<DFB extends DecayFunctionBuilder<DFB>
|
|||
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));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -104,16 +104,6 @@ public enum MultiValueMode implements Writeable {
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeEnum(this);
|
||||
|
|
|
@ -41,7 +41,6 @@ import org.elasticsearch.index.fielddata.FieldData;
|
|||
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 class MultiValueModeTests extends ESTestCase {
|
|||
docsWithValue.set(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final Supplier<SortedNumericDocValues> multiValues = () -> DocValues.singleton(new AbstractNumericDocValues() {
|
||||
int docId = -1;
|
||||
@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() {
|
||||
assertThat(MultiValueMode.SUM.ordinal(), equalTo(0));
|
||||
assertThat(MultiValueMode.AVG.ordinal(), equalTo(1));
|
||||
|
|
Loading…
Reference in New Issue