mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-27 10:28:28 +00:00
lang-expressions should use DoubleValuesSource, not ValueSource (#53661)
DoubleValuesSource is the type-safe replacement for ValueSource in the lucene core. Most of elasticsearch has moved to use these, but lang-expressions is still using the old version. This commit migrates lang-expressions as well.
This commit is contained in:
parent
754d071c4e
commit
0c010e1bfc
@ -19,44 +19,36 @@
|
||||
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A ValueSource to create FunctionValues to get the count of the number of values in a field for a document.
|
||||
*/
|
||||
final class CountMethodValueSource extends ValueSource {
|
||||
IndexFieldData<?> fieldData;
|
||||
final class CountMethodValueSource extends FieldDataBasedDoubleValuesSource {
|
||||
|
||||
CountMethodValueSource(IndexFieldData<?> fieldData) {
|
||||
Objects.requireNonNull(fieldData);
|
||||
|
||||
this.fieldData = fieldData;
|
||||
super(fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes") // ValueSource uses a rawtype
|
||||
public FunctionValues getValues(Map context, LeafReaderContext leaf) throws IOException {
|
||||
LeafNumericFieldData leafData = (LeafNumericFieldData) fieldData.load(leaf);
|
||||
public DoubleValues getValues(LeafReaderContext ctx, DoubleValues scores) {
|
||||
LeafNumericFieldData leafData = (LeafNumericFieldData) fieldData.load(ctx);
|
||||
final SortedNumericDoubleValues values = leafData.getDoubleValues();
|
||||
|
||||
return new DoubleDocValues(this) {
|
||||
return new DoubleValues() {
|
||||
@Override
|
||||
public double doubleVal(int doc) throws IOException {
|
||||
if (values.advanceExact(doc)) {
|
||||
return values.docValueCount();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
public double doubleValue() {
|
||||
return values.docValueCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
return values.advanceExact(doc);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -65,19 +57,18 @@ final class CountMethodValueSource extends ValueSource {
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
FieldDataValueSource that = (FieldDataValueSource) o;
|
||||
|
||||
CountMethodValueSource that = (CountMethodValueSource) o;
|
||||
return fieldData.equals(that.fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "count: field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * getClass().hashCode() + fieldData.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "count: field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,12 @@ package org.elasticsearch.script.expression;
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Expressions API for date fields.
|
||||
*/
|
||||
@ -56,7 +56,7 @@ final class DateField {
|
||||
static final String GET_MINUTES_METHOD = "getMinutes";
|
||||
static final String GET_SECONDS_METHOD = "getSeconds";
|
||||
|
||||
static ValueSource getVariable(IndexFieldData<?> fieldData, String fieldName, String variable) {
|
||||
static DoubleValuesSource getVariable(IndexFieldData<?> fieldData, String fieldName, String variable) {
|
||||
switch (variable) {
|
||||
case VALUE_VARIABLE:
|
||||
return new FieldDataValueSource(fieldData, MultiValueMode.MIN);
|
||||
@ -69,7 +69,7 @@ final class DateField {
|
||||
}
|
||||
}
|
||||
|
||||
static ValueSource getMethod(IndexFieldData<?> fieldData, String fieldName, String method) {
|
||||
static DoubleValuesSource getMethod(IndexFieldData<?> fieldData, String fieldName, String method) {
|
||||
switch (method) {
|
||||
case GETVALUE_METHOD:
|
||||
return new FieldDataValueSource(fieldData, MultiValueMode.MIN);
|
||||
|
@ -19,21 +19,19 @@
|
||||
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/** Extracts a portion of a date field with {@code Calendar.get()} */
|
||||
class DateMethodValueSource extends FieldDataValueSource {
|
||||
|
||||
@ -50,27 +48,26 @@ class DateMethodValueSource extends FieldDataValueSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes") // ValueSource uses a rawtype
|
||||
public FunctionValues getValues(Map context, LeafReaderContext leaf) throws IOException {
|
||||
public DoubleValues getValues(LeafReaderContext leaf, DoubleValues scores) {
|
||||
LeafNumericFieldData leafData = (LeafNumericFieldData) fieldData.load(leaf);
|
||||
final Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.ROOT);
|
||||
NumericDoubleValues docValues = multiValueMode.select(leafData.getDoubleValues());
|
||||
return new DoubleDocValues(this) {
|
||||
return new DoubleValues() {
|
||||
@Override
|
||||
public double doubleVal(int docId) throws IOException {
|
||||
if (docValues.advanceExact(docId)) {
|
||||
long millis = (long)docValues.doubleValue();
|
||||
calendar.setTimeInMillis(millis);
|
||||
return calendar.get(calendarType);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
public double doubleValue() throws IOException {
|
||||
calendar.setTimeInMillis((long)docValues.doubleValue());
|
||||
return calendar.get(calendarType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
return docValues.advanceExact(doc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
public String toString() {
|
||||
return methodName + ": field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ package org.elasticsearch.script.expression;
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
import org.joda.time.ReadableDateTime;
|
||||
@ -30,7 +30,7 @@ import org.joda.time.ReadableDateTime;
|
||||
final class DateObject {
|
||||
// no instance
|
||||
private DateObject() {}
|
||||
|
||||
|
||||
// supported variables
|
||||
static final String CENTURY_OF_ERA_VARIABLE = "centuryOfEra";
|
||||
static final String DAY_OF_MONTH_VARIABLE = "dayOfMonth";
|
||||
@ -50,7 +50,7 @@ final class DateObject {
|
||||
static final String YEAR_VARIABLE = "year";
|
||||
static final String YEAR_OF_CENTURY_VARIABLE = "yearOfCentury";
|
||||
static final String YEAR_OF_ERA_VARIABLE = "yearOfEra";
|
||||
|
||||
|
||||
// supported methods
|
||||
static final String GETCENTURY_OF_ERA_METHOD = "getCenturyOfEra";
|
||||
static final String GETDAY_OF_MONTH_METHOD = "getDayOfMonth";
|
||||
@ -70,8 +70,8 @@ final class DateObject {
|
||||
static final String GETYEAR_METHOD = "getYear";
|
||||
static final String GETYEAR_OF_CENTURY_METHOD = "getYearOfCentury";
|
||||
static final String GETYEAR_OF_ERA_METHOD = "getYearOfEra";
|
||||
|
||||
static ValueSource getVariable(IndexFieldData<?> fieldData, String fieldName, String variable) {
|
||||
|
||||
static DoubleValuesSource getVariable(IndexFieldData<?> fieldData, String fieldName, String variable) {
|
||||
switch (variable) {
|
||||
case CENTURY_OF_ERA_VARIABLE:
|
||||
return new DateObjectValueSource(fieldData, MultiValueMode.MIN, variable, ReadableDateTime::getCenturyOfEra);
|
||||
@ -110,12 +110,12 @@ final class DateObject {
|
||||
case YEAR_OF_ERA_VARIABLE:
|
||||
return new DateObjectValueSource(fieldData, MultiValueMode.MIN, variable, ReadableDateTime::getYearOfEra);
|
||||
default:
|
||||
throw new IllegalArgumentException("Member variable [" + variable +
|
||||
throw new IllegalArgumentException("Member variable [" + variable +
|
||||
"] does not exist for date object on field [" + fieldName + "].");
|
||||
}
|
||||
}
|
||||
|
||||
static ValueSource getMethod(IndexFieldData<?> fieldData, String fieldName, String method) {
|
||||
|
||||
static DoubleValuesSource getMethod(IndexFieldData<?> fieldData, String fieldName, String method) {
|
||||
switch (method) {
|
||||
case GETCENTURY_OF_ERA_METHOD:
|
||||
return new DateObjectValueSource(fieldData, MultiValueMode.MIN, method, ReadableDateTime::getCenturyOfEra);
|
||||
@ -154,7 +154,7 @@ final class DateObject {
|
||||
case GETYEAR_OF_ERA_METHOD:
|
||||
return new DateObjectValueSource(fieldData, MultiValueMode.MIN, method, ReadableDateTime::getYearOfEra);
|
||||
default:
|
||||
throw new IllegalArgumentException("Member method [" + method +
|
||||
throw new IllegalArgumentException("Member method [" + method +
|
||||
"] does not exist for date object on field [" + fieldName + "].");
|
||||
}
|
||||
}
|
||||
|
@ -19,14 +19,8 @@
|
||||
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.ToIntFunction;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
||||
@ -35,6 +29,10 @@ import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.MutableDateTime;
|
||||
import org.joda.time.ReadableDateTime;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.function.ToIntFunction;
|
||||
|
||||
/** Extracts a portion of a date field with joda time */
|
||||
class DateObjectValueSource extends FieldDataValueSource {
|
||||
|
||||
@ -52,27 +50,26 @@ class DateObjectValueSource extends FieldDataValueSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes") // ValueSource uses a rawtype
|
||||
public FunctionValues getValues(Map context, LeafReaderContext leaf) throws IOException {
|
||||
public DoubleValues getValues(LeafReaderContext leaf, DoubleValues scores) {
|
||||
LeafNumericFieldData leafData = (LeafNumericFieldData) fieldData.load(leaf);
|
||||
MutableDateTime joda = new MutableDateTime(0, DateTimeZone.UTC);
|
||||
NumericDoubleValues docValues = multiValueMode.select(leafData.getDoubleValues());
|
||||
return new DoubleDocValues(this) {
|
||||
return DoubleValues.withDefault(new DoubleValues() {
|
||||
@Override
|
||||
public double doubleVal(int docId) throws IOException {
|
||||
if (docValues.advanceExact(docId)) {
|
||||
long millis = (long)docValues.doubleValue();
|
||||
joda.setMillis(millis);
|
||||
return function.applyAsInt(joda);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
public double doubleValue() throws IOException {
|
||||
joda.setMillis((long)docValues.doubleValue());
|
||||
return function.applyAsInt(joda);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
return docValues.advanceExact(doc);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
public String toString() {
|
||||
return methodName + ": field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
|
||||
|
@ -20,44 +20,39 @@
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* ValueSource to return non-zero if a field is missing.
|
||||
* <p>
|
||||
* This is essentially sugar over !count()
|
||||
*/
|
||||
final class EmptyMemberValueSource extends ValueSource {
|
||||
final IndexFieldData<?> fieldData;
|
||||
final class EmptyMemberValueSource extends FieldDataBasedDoubleValuesSource {
|
||||
|
||||
EmptyMemberValueSource(IndexFieldData<?> fieldData) {
|
||||
this.fieldData = Objects.requireNonNull(fieldData);
|
||||
super(fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes") // ValueSource uses a rawtype
|
||||
public FunctionValues getValues(Map context, LeafReaderContext leaf) throws IOException {
|
||||
public DoubleValues getValues(LeafReaderContext leaf, DoubleValues scores) {
|
||||
LeafNumericFieldData leafData = (LeafNumericFieldData) fieldData.load(leaf);
|
||||
final SortedNumericDoubleValues values = leafData.getDoubleValues();
|
||||
return new DoubleDocValues(this) {
|
||||
return DoubleValues.withDefault(new DoubleValues() {
|
||||
@Override
|
||||
public double doubleVal(int doc) throws IOException {
|
||||
if (values.advanceExact(doc)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
public double doubleValue() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
return values.advanceExact(doc);
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,12 +66,12 @@ final class EmptyMemberValueSource extends ValueSource {
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
EmptyMemberValueSource other = (EmptyMemberValueSource) obj;
|
||||
if (!fieldData.equals(other.fieldData)) return false;
|
||||
return true;
|
||||
return fieldData.equals(other.fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
public String toString() {
|
||||
return "empty: field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ import org.apache.lucene.expressions.Expression;
|
||||
import org.apache.lucene.expressions.SimpleBindings;
|
||||
import org.apache.lucene.expressions.js.JavascriptCompiler;
|
||||
import org.apache.lucene.expressions.js.VariableContext;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.valuesource.DoubleConstValueSource;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.SortField;
|
||||
import org.elasticsearch.SpecialPermission;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
@ -256,9 +256,9 @@ public class ExpressionScriptEngine implements ScriptEngine {
|
||||
} else {
|
||||
// delegate valuesource creation based on field's type
|
||||
// there are three types of "fields" to expressions, and each one has a different "api" of variables and methods.
|
||||
final ValueSource valueSource = getDocValueSource(variable, lookup);
|
||||
needsScores |= valueSource.getSortField(false).needsScores();
|
||||
bindings.add(variable, valueSource.asDoubleValuesSource());
|
||||
final DoubleValuesSource valueSource = getDocValueSource(variable, lookup);
|
||||
needsScores |= valueSource.needsScores();
|
||||
bindings.add(variable, valueSource);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// we defer "binding" of variables until here: give context for that variable
|
||||
@ -280,8 +280,7 @@ public class ExpressionScriptEngine implements ScriptEngine {
|
||||
} else {
|
||||
// delegate valuesource creation based on field's type
|
||||
// there are three types of "fields" to expressions, and each one has a different "api" of variables and methods.
|
||||
final ValueSource valueSource = getDocValueSource(variable, lookup);
|
||||
bindings.add(variable, valueSource.asDoubleValuesSource());
|
||||
bindings.add(variable, getDocValueSource(variable, lookup));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// we defer "binding" of variables until here: give context for that variable
|
||||
@ -315,9 +314,9 @@ public class ExpressionScriptEngine implements ScriptEngine {
|
||||
} else {
|
||||
// delegate valuesource creation based on field's type
|
||||
// there are three types of "fields" to expressions, and each one has a different "api" of variables and methods.
|
||||
final ValueSource valueSource = getDocValueSource(variable, lookup);
|
||||
needsScores |= valueSource.getSortField(false).needsScores();
|
||||
bindings.add(variable, valueSource.asDoubleValuesSource());
|
||||
final DoubleValuesSource valueSource = getDocValueSource(variable, lookup);
|
||||
needsScores |= valueSource.needsScores();
|
||||
bindings.add(variable, valueSource);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// we defer "binding" of variables until here: give context for that variable
|
||||
@ -334,8 +333,7 @@ public class ExpressionScriptEngine implements ScriptEngine {
|
||||
if (vars != null && vars.containsKey(variable)) {
|
||||
bindFromParams(vars, bindings, variable);
|
||||
} else {
|
||||
final ValueSource valueSource = getDocValueSource(variable, lookup);
|
||||
bindings.add(variable, valueSource.asDoubleValuesSource());
|
||||
bindings.add(variable, getDocValueSource(variable, lookup));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw convertToScriptException("link error", expr.sourceText, variable, e);
|
||||
@ -387,9 +385,9 @@ public class ExpressionScriptEngine implements ScriptEngine {
|
||||
} else {
|
||||
// delegate valuesource creation based on field's type
|
||||
// there are three types of "fields" to expressions, and each one has a different "api" of variables and methods.
|
||||
final ValueSource valueSource = getDocValueSource(variable, lookup);
|
||||
needsScores |= valueSource.getSortField(false).needsScores();
|
||||
bindings.add(variable, valueSource.asDoubleValuesSource());
|
||||
final DoubleValuesSource valueSource = getDocValueSource(variable, lookup);
|
||||
needsScores |= valueSource.needsScores();
|
||||
bindings.add(variable, valueSource);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// we defer "binding" of variables until here: give context for that variable
|
||||
@ -417,7 +415,7 @@ public class ExpressionScriptEngine implements ScriptEngine {
|
||||
throw new ScriptException(message, cause, stack, source, NAME);
|
||||
}
|
||||
|
||||
private static ValueSource getDocValueSource(String variable, SearchLookup lookup) throws ParseException {
|
||||
private static DoubleValuesSource getDocValueSource(String variable, SearchLookup lookup) throws ParseException {
|
||||
VariableContext[] parts = VariableContext.parse(variable);
|
||||
if (parts[0].text.equals("doc") == false) {
|
||||
throw new ParseException("Unknown variable [" + parts[0].text + "]", 0);
|
||||
@ -468,7 +466,7 @@ public class ExpressionScriptEngine implements ScriptEngine {
|
||||
}
|
||||
|
||||
IndexFieldData<?> fieldData = lookup.doc().getForField(fieldType);
|
||||
final ValueSource valueSource;
|
||||
final DoubleValuesSource valueSource;
|
||||
if (fieldType instanceof GeoPointFieldType) {
|
||||
// geo
|
||||
if (methodname == null) {
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import org.apache.lucene.index.DocValues;
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
abstract class FieldDataBasedDoubleValuesSource extends DoubleValuesSource {
|
||||
|
||||
FieldDataBasedDoubleValuesSource(IndexFieldData<?> fieldData) {
|
||||
this.fieldData = Objects.requireNonNull(fieldData);
|
||||
}
|
||||
|
||||
protected final IndexFieldData<?> fieldData;
|
||||
|
||||
@Override
|
||||
public boolean needsScores() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleValuesSource rewrite(IndexSearcher reader) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCacheable(LeafReaderContext ctx) {
|
||||
return DocValues.isCacheable(ctx, fieldData.getFieldName());
|
||||
}
|
||||
|
||||
}
|
@ -19,29 +19,26 @@
|
||||
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.LeafNumericFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.NumericDoubleValues;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A {@link ValueSource} wrapper for field data.
|
||||
*/
|
||||
class FieldDataValueSource extends ValueSource {
|
||||
class FieldDataValueSource extends FieldDataBasedDoubleValuesSource {
|
||||
|
||||
final IndexFieldData<?> fieldData;
|
||||
final MultiValueMode multiValueMode;
|
||||
|
||||
protected FieldDataValueSource(IndexFieldData<?> fieldData, MultiValueMode multiValueMode) {
|
||||
this.fieldData = Objects.requireNonNull(fieldData);
|
||||
super(fieldData);
|
||||
this.multiValueMode = Objects.requireNonNull(multiValueMode);
|
||||
}
|
||||
|
||||
@ -65,24 +62,25 @@ class FieldDataValueSource extends ValueSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes") // ValueSource uses a rawtype
|
||||
public FunctionValues getValues(Map context, LeafReaderContext leaf) throws IOException {
|
||||
public DoubleValues getValues(LeafReaderContext leaf, DoubleValues scores) {
|
||||
LeafNumericFieldData leafData = (LeafNumericFieldData) fieldData.load(leaf);
|
||||
NumericDoubleValues docValues = multiValueMode.select(leafData.getDoubleValues());
|
||||
return new DoubleDocValues(this) {
|
||||
@Override
|
||||
public double doubleVal(int doc) throws IOException {
|
||||
if (docValues.advanceExact(doc)) {
|
||||
return new DoubleValues() {
|
||||
@Override
|
||||
public double doubleValue() throws IOException {
|
||||
return docValues.doubleValue();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
return docValues.advanceExact(doc);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
public String toString() {
|
||||
return "field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,43 +19,38 @@
|
||||
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.elasticsearch.index.fielddata.LeafGeoPointFieldData;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.LeafGeoPointFieldData;
|
||||
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* ValueSource to return non-zero if a field is missing.
|
||||
*/
|
||||
final class GeoEmptyValueSource extends ValueSource {
|
||||
IndexFieldData<?> fieldData;
|
||||
final class GeoEmptyValueSource extends FieldDataBasedDoubleValuesSource {
|
||||
|
||||
GeoEmptyValueSource(IndexFieldData<?> fieldData) {
|
||||
this.fieldData = Objects.requireNonNull(fieldData);
|
||||
super(fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes") // ValueSource uses a rawtype
|
||||
public FunctionValues getValues(Map context, LeafReaderContext leaf) throws IOException {
|
||||
public DoubleValues getValues(LeafReaderContext leaf, DoubleValues scores) {
|
||||
LeafGeoPointFieldData leafData = (LeafGeoPointFieldData) fieldData.load(leaf);
|
||||
final MultiGeoPointValues values = leafData.getGeoPointValues();
|
||||
return new DoubleDocValues(this) {
|
||||
return DoubleValues.withDefault(new DoubleValues() {
|
||||
@Override
|
||||
public double doubleVal(int doc) throws IOException {
|
||||
if (values.advanceExact(doc)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
public double doubleValue() {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
return values.advanceExact(doc);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -69,12 +64,12 @@ final class GeoEmptyValueSource extends ValueSource {
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
GeoEmptyValueSource other = (GeoEmptyValueSource) obj;
|
||||
if (!fieldData.equals(other.fieldData)) return false;
|
||||
return true;
|
||||
return fieldData.equals(other.fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
public String toString() {
|
||||
return "empty: field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ package org.elasticsearch.script.expression;
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
|
||||
/**
|
||||
@ -28,18 +28,18 @@ import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
final class GeoField {
|
||||
// no instance
|
||||
private GeoField() {}
|
||||
|
||||
|
||||
// supported variables
|
||||
static final String EMPTY_VARIABLE = "empty";
|
||||
static final String LAT_VARIABLE = "lat";
|
||||
static final String LON_VARIABLE = "lon";
|
||||
|
||||
|
||||
// supported methods
|
||||
static final String ISEMPTY_METHOD = "isEmpty";
|
||||
static final String GETLAT_METHOD = "getLat";
|
||||
static final String GETLON_METHOD = "getLon";
|
||||
|
||||
static ValueSource getVariable(IndexFieldData<?> fieldData, String fieldName, String variable) {
|
||||
|
||||
static DoubleValuesSource getVariable(IndexFieldData<?> fieldData, String fieldName, String variable) {
|
||||
switch (variable) {
|
||||
case EMPTY_VARIABLE:
|
||||
return new GeoEmptyValueSource(fieldData);
|
||||
@ -51,8 +51,8 @@ final class GeoField {
|
||||
throw new IllegalArgumentException("Member variable [" + variable + "] does not exist for geo field [" + fieldName + "].");
|
||||
}
|
||||
}
|
||||
|
||||
static ValueSource getMethod(IndexFieldData<?> fieldData, String fieldName, String method) {
|
||||
|
||||
static DoubleValuesSource getMethod(IndexFieldData<?> fieldData, String fieldName, String method) {
|
||||
switch (method) {
|
||||
case ISEMPTY_METHOD:
|
||||
return new GeoEmptyValueSource(fieldData);
|
||||
|
@ -19,43 +19,38 @@
|
||||
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.LeafGeoPointFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* ValueSource to return latitudes as a double "stream" for geopoint fields
|
||||
*/
|
||||
final class GeoLatitudeValueSource extends ValueSource {
|
||||
final IndexFieldData<?> fieldData;
|
||||
final class GeoLatitudeValueSource extends FieldDataBasedDoubleValuesSource {
|
||||
|
||||
GeoLatitudeValueSource(IndexFieldData<?> fieldData) {
|
||||
this.fieldData = Objects.requireNonNull(fieldData);
|
||||
super(fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes") // ValueSource uses a rawtype
|
||||
public FunctionValues getValues(Map context, LeafReaderContext leaf) throws IOException {
|
||||
public DoubleValues getValues(LeafReaderContext leaf, DoubleValues scores) {
|
||||
LeafGeoPointFieldData leafData = (LeafGeoPointFieldData) fieldData.load(leaf);
|
||||
final MultiGeoPointValues values = leafData.getGeoPointValues();
|
||||
return new DoubleDocValues(this) {
|
||||
return DoubleValues.withDefault(new DoubleValues() {
|
||||
@Override
|
||||
public double doubleVal(int doc) throws IOException {
|
||||
if (values.advanceExact(doc)) {
|
||||
return values.nextValue().getLat();
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
public double doubleValue() throws IOException {
|
||||
return values.nextValue().getLat();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
return values.advanceExact(doc);
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -69,12 +64,11 @@ final class GeoLatitudeValueSource extends ValueSource {
|
||||
if (obj == null) return false;
|
||||
if (getClass() != obj.getClass()) return false;
|
||||
GeoLatitudeValueSource other = (GeoLatitudeValueSource) obj;
|
||||
if (!fieldData.equals(other.fieldData)) return false;
|
||||
return true;
|
||||
return fieldData.equals(other.fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
public String toString() {
|
||||
return "lat: field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
}
|
||||
|
@ -19,43 +19,38 @@
|
||||
|
||||
package org.elasticsearch.script.expression;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.lucene.index.LeafReaderContext;
|
||||
import org.apache.lucene.queries.function.FunctionValues;
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.queries.function.docvalues.DoubleDocValues;
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
import org.elasticsearch.index.fielddata.LeafGeoPointFieldData;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.index.fielddata.MultiGeoPointValues;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* ValueSource to return longitudes as a double "stream" for geopoint fields
|
||||
*/
|
||||
final class GeoLongitudeValueSource extends ValueSource {
|
||||
final IndexFieldData<?> fieldData;
|
||||
final class GeoLongitudeValueSource extends FieldDataBasedDoubleValuesSource {
|
||||
|
||||
GeoLongitudeValueSource(IndexFieldData<?> fieldData) {
|
||||
this.fieldData = Objects.requireNonNull(fieldData);
|
||||
super(fieldData);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes") // ValueSource uses a rawtype
|
||||
public FunctionValues getValues(Map context, LeafReaderContext leaf) throws IOException {
|
||||
public DoubleValues getValues(LeafReaderContext leaf, DoubleValues scores) {
|
||||
LeafGeoPointFieldData leafData = (LeafGeoPointFieldData) fieldData.load(leaf);
|
||||
final MultiGeoPointValues values = leafData.getGeoPointValues();
|
||||
return new DoubleDocValues(this) {
|
||||
return DoubleValues.withDefault(new DoubleValues() {
|
||||
@Override
|
||||
public double doubleVal(int doc) throws IOException {
|
||||
if (values.advanceExact(doc)) {
|
||||
return values.nextValue().getLon();
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
public double doubleValue() throws IOException {
|
||||
return values.nextValue().getLon();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
return values.advanceExact(doc);
|
||||
}
|
||||
}, 0.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -74,7 +69,7 @@ final class GeoLongitudeValueSource extends ValueSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
public String toString() {
|
||||
return "lon: field(" + fieldData.getFieldName() + ")";
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ package org.elasticsearch.script.expression;
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import org.apache.lucene.queries.function.ValueSource;
|
||||
import org.apache.lucene.search.DoubleValuesSource;
|
||||
import org.elasticsearch.index.fielddata.IndexFieldData;
|
||||
import org.elasticsearch.search.MultiValueMode;
|
||||
|
||||
@ -46,7 +46,7 @@ final class NumericField {
|
||||
static final String SUM_METHOD = "sum";
|
||||
static final String COUNT_METHOD = "count";
|
||||
|
||||
static ValueSource getVariable(IndexFieldData<?> fieldData, String fieldName, String variable) {
|
||||
static DoubleValuesSource getVariable(IndexFieldData<?> fieldData, String fieldName, String variable) {
|
||||
switch (variable) {
|
||||
case VALUE_VARIABLE:
|
||||
return new FieldDataValueSource(fieldData, MultiValueMode.MIN);
|
||||
@ -60,7 +60,7 @@ final class NumericField {
|
||||
}
|
||||
}
|
||||
|
||||
static ValueSource getMethod(IndexFieldData<?> fieldData, String fieldName, String method) {
|
||||
static DoubleValuesSource getMethod(IndexFieldData<?> fieldData, String fieldName, String method) {
|
||||
switch (method) {
|
||||
case GETVALUE_METHOD:
|
||||
return new FieldDataValueSource(fieldData, MultiValueMode.MIN);
|
||||
|
@ -80,7 +80,7 @@ final class ReplaceableConstDoubleValueSource extends DoubleValuesSource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoubleValuesSource rewrite(IndexSearcher reader) throws IOException {
|
||||
public DoubleValuesSource rewrite(IndexSearcher reader) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,6 @@ package org.elasticsearch.script.expression;
|
||||
|
||||
import org.apache.lucene.search.DoubleValues;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A support class for an executable expression script that allows the double returned
|
||||
* by a {@link DoubleValues} to be modified.
|
||||
@ -35,12 +33,12 @@ final class ReplaceableConstDoubleValues extends DoubleValues {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() throws IOException {
|
||||
public double doubleValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean advanceExact(int doc) throws IOException {
|
||||
public boolean advanceExact(int doc) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user