org.elasticsearch.index.query.functionscore.DecayFunctionParser Maven / Gradle / Ivy
Show all versions of elasticsearch Show documentation
/*
* 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.index.query.functionscore;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.plugins.SearchPlugin;
import org.elasticsearch.search.MultiValueMode;
import org.elasticsearch.search.SearchModule;
import java.io.IOException;
import java.util.function.BiFunction;
/**
* Parser used for all decay functions, one instance each. It parses this kind
* of input:
*
*
*
* {
* "fieldname1" : {
* "origin" = "someValue",
* "scale" = "someValue"
* },
* "multi_value_mode" : "min"
* }
*
*
*
* "origin" here refers to the reference point and "scale" to the level of
* uncertainty you have in your origin.
*
*
* For example, you might want to retrieve an event that took place around the
* 20 May 2010 somewhere near Berlin. You are mainly interested in events that
* are close to the 20 May 2010 but you are unsure about your guess, maybe it
* was a week before or after that. Your "origin" for the date field would be
* "20 May 2010" and your "scale" would be "7d".
*
*
* This class parses the input and creates a scoring function from the
* parameters origin and scale.
*
* To write a new decay scoring function, create a new class that extends
* {@link DecayFunctionBuilder}, setup a PARSER field with this class, and
* register them in {@link SearchModule#registerScoreFunctions} or {@link SearchPlugin#getScoreFunctions}
* See {@link GaussDecayFunctionBuilder#PARSER} for an example.
*/
public final class DecayFunctionParser> implements ScoreFunctionParser {
public static final ParseField MULTI_VALUE_MODE = new ParseField("multi_value_mode");
private final BiFunction createFromBytes;
/**
* Create the parser using a method reference to a "create from bytes" constructor for the {@linkplain DecayFunctionBuilder}. We use a
* method reference here so each use of this class doesn't have to subclass it.
*/
public DecayFunctionParser(BiFunction createFromBytes) {
this.createFromBytes = createFromBytes;
}
/**
* Parses bodies of the kind
*
*
*
* {
* "fieldname1" : {
* "origin" : "someValue",
* "scale" : "someValue"
* },
* "multi_value_mode" : "min"
* }
*
*
*/
@Override
public DFB fromXContent(QueryParseContext context) throws IOException, ParsingException {
XContentParser parser = context.parser();
String currentFieldName;
XContentParser.Token token;
MultiValueMode multiValueMode = DecayFunctionBuilder.DEFAULT_MULTI_VALUE_MODE;
String fieldName = null;
BytesReference functionBytes = null;
while ((token = parser.nextToken()) == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
token = parser.nextToken();
if (token == XContentParser.Token.START_OBJECT) {
fieldName = currentFieldName;
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.copyCurrentStructure(parser);
functionBytes = builder.bytes();
} else if (context.getParseFieldMatcher().match(currentFieldName, MULTI_VALUE_MODE)) {
multiValueMode = MultiValueMode.fromString(parser.text());
} else {
throw new ParsingException(parser.getTokenLocation(), "malformed score function score parameters.");
}
}
if (fieldName == null || functionBytes == null) {
throw new ParsingException(parser.getTokenLocation(), "malformed score function score parameters.");
}
DFB functionBuilder = createFromBytes.apply(fieldName, functionBytes);
functionBuilder.setMultiValueMode(multiValueMode);
return functionBuilder;
}
}