Use ConstructingObjectParser for parsing DirectCandidateGenerator
When refactoring DirectCandidateGeneratorBuilder recently, the ConstructingObjectParser that we have today was not available. Instead we used some workaround, but it is better to remove this now and use ConstructingObjectParser instead.
This commit is contained in:
parent
82881ef99a
commit
ba4a3db03b
|
@ -29,10 +29,9 @@ import org.apache.lucene.search.spell.SuggestMode;
|
|||
import org.apache.lucene.util.automaton.LevenshteinAutomata;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.index.mapper.MapperService;
|
||||
|
@ -41,10 +40,8 @@ import org.elasticsearch.search.suggest.SortBy;
|
|||
import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder.CandidateGenerator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public final class DirectCandidateGeneratorBuilder implements CandidateGenerator {
|
||||
|
@ -89,30 +86,6 @@ public final class DirectCandidateGeneratorBuilder implements CandidateGenerator
|
|||
this.field = field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quasi copy-constructor that takes all values from the generator
|
||||
* passed in, but uses different field name. Needed by parser because we
|
||||
* need to buffer the field name but read all other properties to a
|
||||
* temporary object.
|
||||
*/
|
||||
private static DirectCandidateGeneratorBuilder replaceField(String field, DirectCandidateGeneratorBuilder other) {
|
||||
DirectCandidateGeneratorBuilder generator = new DirectCandidateGeneratorBuilder(field);
|
||||
generator.preFilter = other.preFilter;
|
||||
generator.postFilter = other.postFilter;
|
||||
generator.suggestMode = other.suggestMode;
|
||||
generator.accuracy = other.accuracy;
|
||||
generator.size = other.size;
|
||||
generator.sort = other.sort;
|
||||
generator.stringDistance = other.stringDistance;
|
||||
generator.maxEdits = other.maxEdits;
|
||||
generator.maxInspections = other.maxInspections;
|
||||
generator.maxTermFreq = other.maxTermFreq;
|
||||
generator.prefixLength = other.prefixLength;
|
||||
generator.minWordLength = other.minWordLength;
|
||||
generator.minDocFreq = other.minDocFreq;
|
||||
return generator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from a stream.
|
||||
*/
|
||||
|
@ -358,35 +331,28 @@ public final class DirectCandidateGeneratorBuilder implements CandidateGenerator
|
|||
}
|
||||
}
|
||||
|
||||
private static ObjectParser<Tuple<Set<String>, DirectCandidateGeneratorBuilder>, QueryParseContext> PARSER = new ObjectParser<>(TYPE);
|
||||
private static ConstructingObjectParser<DirectCandidateGeneratorBuilder, QueryParseContext> PARSER = new ConstructingObjectParser<>(
|
||||
TYPE, args -> new DirectCandidateGeneratorBuilder((String) args[0]));
|
||||
|
||||
static {
|
||||
PARSER.declareString((tp, s) -> tp.v1().add(s), FIELDNAME_FIELD);
|
||||
PARSER.declareString((tp, s) -> tp.v2().preFilter(s), PREFILTER_FIELD);
|
||||
PARSER.declareString((tp, s) -> tp.v2().postFilter(s), POSTFILTER_FIELD);
|
||||
PARSER.declareString((tp, s) -> tp.v2().suggestMode(s), SUGGESTMODE_FIELD);
|
||||
PARSER.declareFloat((tp, f) -> tp.v2().minDocFreq(f), MIN_DOC_FREQ_FIELD);
|
||||
PARSER.declareFloat((tp, f) -> tp.v2().accuracy(f), ACCURACY_FIELD);
|
||||
PARSER.declareInt((tp, i) -> tp.v2().size(i), SIZE_FIELD);
|
||||
PARSER.declareString((tp, s) -> tp.v2().sort(s), SORT_FIELD);
|
||||
PARSER.declareString((tp, s) -> tp.v2().stringDistance(s), STRING_DISTANCE_FIELD);
|
||||
PARSER.declareInt((tp, i) -> tp.v2().maxInspections(i), MAX_INSPECTIONS_FIELD);
|
||||
PARSER.declareFloat((tp, f) -> tp.v2().maxTermFreq(f), MAX_TERM_FREQ_FIELD);
|
||||
PARSER.declareInt((tp, i) -> tp.v2().maxEdits(i), MAX_EDITS_FIELD);
|
||||
PARSER.declareInt((tp, i) -> tp.v2().minWordLength(i), MIN_WORD_LENGTH_FIELD);
|
||||
PARSER.declareInt((tp, i) -> tp.v2().prefixLength(i), PREFIX_LENGTH_FIELD);
|
||||
PARSER.declareString(ConstructingObjectParser.constructorArg(), FIELDNAME_FIELD);
|
||||
PARSER.declareString(DirectCandidateGeneratorBuilder::preFilter, PREFILTER_FIELD);
|
||||
PARSER.declareString(DirectCandidateGeneratorBuilder::postFilter, POSTFILTER_FIELD);
|
||||
PARSER.declareString(DirectCandidateGeneratorBuilder::suggestMode, SUGGESTMODE_FIELD);
|
||||
PARSER.declareFloat(DirectCandidateGeneratorBuilder::minDocFreq, MIN_DOC_FREQ_FIELD);
|
||||
PARSER.declareFloat(DirectCandidateGeneratorBuilder::accuracy, ACCURACY_FIELD);
|
||||
PARSER.declareInt(DirectCandidateGeneratorBuilder::size, SIZE_FIELD);
|
||||
PARSER.declareString(DirectCandidateGeneratorBuilder::sort, SORT_FIELD);
|
||||
PARSER.declareString(DirectCandidateGeneratorBuilder::stringDistance, STRING_DISTANCE_FIELD);
|
||||
PARSER.declareInt(DirectCandidateGeneratorBuilder::maxInspections, MAX_INSPECTIONS_FIELD);
|
||||
PARSER.declareFloat(DirectCandidateGeneratorBuilder::maxTermFreq, MAX_TERM_FREQ_FIELD);
|
||||
PARSER.declareInt(DirectCandidateGeneratorBuilder::maxEdits, MAX_EDITS_FIELD);
|
||||
PARSER.declareInt(DirectCandidateGeneratorBuilder::minWordLength, MIN_WORD_LENGTH_FIELD);
|
||||
PARSER.declareInt(DirectCandidateGeneratorBuilder::prefixLength, PREFIX_LENGTH_FIELD);
|
||||
}
|
||||
|
||||
public static DirectCandidateGeneratorBuilder fromXContent(QueryParseContext parseContext) throws IOException {
|
||||
DirectCandidateGeneratorBuilder tempGenerator = new DirectCandidateGeneratorBuilder("_na_");
|
||||
// bucket for the field name, needed as constructor arg later
|
||||
Set<String> tmpFieldName = new HashSet<>(1);
|
||||
PARSER.parse(parseContext.parser(), new Tuple<>(tmpFieldName, tempGenerator),
|
||||
parseContext);
|
||||
if (tmpFieldName.size() != 1) {
|
||||
throw new IllegalArgumentException("[" + TYPE + "] expects exactly one field parameter, but found " + tmpFieldName);
|
||||
}
|
||||
return replaceField(tmpFieldName.iterator().next(), tempGenerator);
|
||||
return PARSER.apply(parseContext.parser(), parseContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.elasticsearch.search.suggest.phrase.PhraseSuggestionContext.DirectCan
|
|||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class DirectCandidateGeneratorTests extends ESTestCase{
|
||||
|
@ -151,12 +152,12 @@ public class DirectCandidateGeneratorTests extends ESTestCase{
|
|||
// test missing fieldname
|
||||
String directGenerator = "{ }";
|
||||
assertIllegalXContent(directGenerator, IllegalArgumentException.class,
|
||||
"[direct_generator] expects exactly one field parameter, but found []");
|
||||
"Required [field]");
|
||||
|
||||
// test two fieldnames
|
||||
directGenerator = "{ \"field\" : \"f1\", \"field\" : \"f2\" }";
|
||||
assertIllegalXContent(directGenerator, IllegalArgumentException.class,
|
||||
"[direct_generator] expects exactly one field parameter, but found [f2, f1]");
|
||||
assertIllegalXContent(directGenerator, ParsingException.class,
|
||||
"[direct_generator] failed to parse field [field]");
|
||||
|
||||
// test unknown field
|
||||
directGenerator = "{ \"unknown_param\" : \"f1\" }";
|
||||
|
|
Loading…
Reference in New Issue