use of org.opensearch.index.fielddata.IndexNumericFieldData in project OpenSearch by opensearch-project.
the class ExpressionScriptEngine method getDocValueSource.
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);
}
if (parts.length < 2 || parts[1].type != VariableContext.Type.STR_INDEX) {
throw new ParseException("Variable 'doc' must be used with a specific field like: doc['myfield']", 3);
}
// .value is the default for doc['field'], its optional.
String variablename = "value";
String methodname = null;
if (parts.length == 3) {
if (parts[2].type == VariableContext.Type.METHOD) {
methodname = parts[2].text;
} else if (parts[2].type == VariableContext.Type.MEMBER) {
variablename = parts[2].text;
} else {
throw new IllegalArgumentException("Only member variables or member methods may be accessed on a field when not accessing the field directly");
}
}
// true if the variable is of type doc['field'].date.xxx
boolean dateAccessor = false;
if (parts.length > 3) {
// access to the .date "object" within the field
if (parts.length == 4 && ("date".equals(parts[2].text) || "getDate".equals(parts[2].text))) {
if (parts[3].type == VariableContext.Type.METHOD) {
methodname = parts[3].text;
dateAccessor = true;
} else if (parts[3].type == VariableContext.Type.MEMBER) {
variablename = parts[3].text;
dateAccessor = true;
}
}
if (!dateAccessor) {
throw new IllegalArgumentException("Variable [" + variable + "] does not follow an allowed format of either doc['field'] or doc['field'].method()");
}
}
String fieldname = parts[1].text;
MappedFieldType fieldType = lookup.doc().mapperService().fieldType(fieldname);
if (fieldType == null) {
throw new ParseException("Field [" + fieldname + "] does not exist in mappings", 5);
}
IndexFieldData<?> fieldData = lookup.doc().getForField(fieldType);
final DoubleValuesSource valueSource;
if (fieldType instanceof GeoPointFieldType) {
// geo
if (methodname == null) {
valueSource = GeoField.getVariable(fieldData, fieldname, variablename);
} else {
valueSource = GeoField.getMethod(fieldData, fieldname, methodname);
}
} else if (fieldType instanceof DateFieldMapper.DateFieldType) {
if (dateAccessor) {
// date object
if (methodname == null) {
valueSource = DateObject.getVariable(fieldData, fieldname, variablename);
} else {
valueSource = DateObject.getMethod(fieldData, fieldname, methodname);
}
} else {
// date field itself
if (methodname == null) {
valueSource = DateField.getVariable(fieldData, fieldname, variablename);
} else {
valueSource = DateField.getMethod(fieldData, fieldname, methodname);
}
}
} else if (fieldData instanceof IndexNumericFieldData) {
// number
if (methodname == null) {
valueSource = NumericField.getVariable(fieldData, fieldname, variablename);
} else {
valueSource = NumericField.getMethod(fieldData, fieldname, methodname);
}
} else {
throw new ParseException("Field [" + fieldname + "] must be numeric, date, or geopoint", 5);
}
return valueSource;
}
use of org.opensearch.index.fielddata.IndexNumericFieldData in project OpenSearch by opensearch-project.
the class DecayFunctionBuilder method parseDateVariable.
private AbstractDistanceScoreFunction parseDateVariable(XContentParser parser, QueryShardContext context, MappedFieldType dateFieldType, MultiValueMode mode) throws IOException {
XContentParser.Token token;
String parameterName = null;
String scaleString = null;
String originString = null;
String offsetString = "0d";
double decay = 0.5;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
parameterName = parser.currentName();
} else if (DecayFunctionBuilder.SCALE.equals(parameterName)) {
scaleString = parser.text();
} else if (DecayFunctionBuilder.ORIGIN.equals(parameterName)) {
originString = parser.text();
} else if (DecayFunctionBuilder.DECAY.equals(parameterName)) {
decay = parser.doubleValue();
} else if (DecayFunctionBuilder.OFFSET.equals(parameterName)) {
offsetString = parser.text();
} else {
throw new OpenSearchParseException("parameter [{}] not supported!", parameterName);
}
}
long origin;
if (originString == null) {
origin = context.nowInMillis();
} else {
origin = ((DateFieldMapper.DateFieldType) dateFieldType).parseToLong(originString, false, null, null, context::nowInMillis);
}
if (scaleString == null) {
throw new OpenSearchParseException("[{}] must be set for date fields.", DecayFunctionBuilder.SCALE);
}
TimeValue val = TimeValue.parseTimeValue(scaleString, TimeValue.timeValueHours(24), DecayFunctionParser.class.getSimpleName() + ".scale");
double scale = val.getMillis();
val = TimeValue.parseTimeValue(offsetString, TimeValue.timeValueHours(24), DecayFunctionParser.class.getSimpleName() + ".offset");
double offset = val.getMillis();
IndexNumericFieldData numericFieldData = context.getForField(dateFieldType);
return new NumericFieldDataScoreFunction(origin, scale, decay, offset, getDecayFunction(), numericFieldData, mode, getFunctionName());
}
use of org.opensearch.index.fielddata.IndexNumericFieldData in project OpenSearch by opensearch-project.
the class DecayFunctionBuilder method parseNumberVariable.
private AbstractDistanceScoreFunction parseNumberVariable(XContentParser parser, QueryShardContext context, MappedFieldType fieldType, MultiValueMode mode) throws IOException {
XContentParser.Token token;
String parameterName = null;
double scale = 0;
double origin = 0;
double decay = 0.5;
double offset = 0.0d;
boolean scaleFound = false;
boolean refFound = false;
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
parameterName = parser.currentName();
} else if (DecayFunctionBuilder.SCALE.equals(parameterName)) {
scale = parser.doubleValue();
scaleFound = true;
} else if (DecayFunctionBuilder.DECAY.equals(parameterName)) {
decay = parser.doubleValue();
} else if (DecayFunctionBuilder.ORIGIN.equals(parameterName)) {
origin = parser.doubleValue();
refFound = true;
} else if (DecayFunctionBuilder.OFFSET.equals(parameterName)) {
offset = parser.doubleValue();
} else {
throw new OpenSearchParseException("parameter [{}] not supported!", parameterName);
}
}
if (!scaleFound || !refFound) {
throw new OpenSearchParseException("both [{}] and [{}] must be set for numeric fields.", DecayFunctionBuilder.SCALE, DecayFunctionBuilder.ORIGIN);
}
IndexNumericFieldData numericFieldData = context.getForField(fieldType);
return new NumericFieldDataScoreFunction(origin, scale, decay, offset, getDecayFunction(), numericFieldData, mode, getFunctionName());
}
use of org.opensearch.index.fielddata.IndexNumericFieldData in project OpenSearch by opensearch-project.
the class ExpressionTermsSetQueryTests method setUp.
@Override
public void setUp() throws Exception {
super.setUp();
NumberFieldType fieldType = new NumberFieldType("field", NumberType.DOUBLE);
MapperService mapperService = mock(MapperService.class);
when(mapperService.fieldType("field")).thenReturn(fieldType);
when(mapperService.fieldType("alias")).thenReturn(fieldType);
SortedNumericDoubleValues doubleValues = mock(SortedNumericDoubleValues.class);
when(doubleValues.advanceExact(anyInt())).thenReturn(true);
when(doubleValues.nextValue()).thenReturn(2.718);
LeafNumericFieldData atomicFieldData = mock(LeafNumericFieldData.class);
when(atomicFieldData.getDoubleValues()).thenReturn(doubleValues);
IndexNumericFieldData fieldData = mock(IndexNumericFieldData.class);
when(fieldData.getFieldName()).thenReturn("field");
when(fieldData.load(any())).thenReturn(atomicFieldData);
service = new ExpressionScriptEngine();
lookup = new SearchLookup(mapperService, (ignored, lookup) -> fieldData);
}
Aggregations