Refactored the term suggestion builder for the query refactoring effort

Added the term suggestion builder's serialization/deserialization and
equals/hashCode methods.
This commit is contained in:
Ali Beyad 2016-01-27 16:05:47 -05:00
parent b7e3323ded
commit 882cd5c6ee
16 changed files with 937 additions and 90 deletions

View File

@ -70,17 +70,9 @@ import static org.elasticsearch.ElasticsearchException.readStackTrace;
public abstract class StreamInput extends InputStream {
private final NamedWriteableRegistry namedWriteableRegistry;
private Version version = Version.CURRENT;
protected StreamInput() {
this.namedWriteableRegistry = new NamedWriteableRegistry();
}
protected StreamInput(NamedWriteableRegistry namedWriteableRegistry) {
this.namedWriteableRegistry = namedWriteableRegistry;
}
protected StreamInput() { }
public Version getVersion() {
return this.version;

View File

@ -55,6 +55,7 @@ import static org.elasticsearch.common.unit.TimeValue.parseTimeValue;
import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.POST;
import static org.elasticsearch.search.suggest.SuggestBuilders.termSuggestion;
import static org.elasticsearch.search.suggest.term.TermSuggestionBuilder.SuggestMode;
/**
*
@ -262,7 +263,9 @@ public class RestSearchAction extends BaseRestHandler {
int suggestSize = request.paramAsInt("suggest_size", 5);
String suggestMode = request.param("suggest_mode");
searchSourceBuilder.suggest(new SuggestBuilder().addSuggestion(
termSuggestion(suggestField).field(suggestField).text(suggestText).size(suggestSize).suggestMode(suggestMode)));
termSuggestion(suggestField).field(suggestField)
.text(suggestText).size(suggestSize)
.suggestMode(SuggestMode.fromString(suggestMode))));
modified = true;
}
return modified;

View File

@ -223,6 +223,10 @@ import org.elasticsearch.search.rescore.QueryRescorerBuilder;
import org.elasticsearch.search.rescore.RescoreBuilder;
import org.elasticsearch.search.suggest.Suggester;
import org.elasticsearch.search.suggest.Suggesters;
import org.elasticsearch.search.suggest.SuggestionBuilder;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder;
import org.elasticsearch.search.suggest.term.TermSuggestionBuilder;
import java.util.ArrayList;
import java.util.HashMap;
@ -365,6 +369,9 @@ public class SearchModule extends AbstractModule {
protected void configureSuggesters() {
suggesters.bind(binder());
namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, TermSuggestionBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, PhraseSuggestionBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, CompletionSuggestionBuilder.PROTOTYPE);
}
protected void configureHighlighters() {

View File

@ -25,16 +25,30 @@ import org.apache.lucene.util.automaton.LevenshteinAutomata;
public class DirectSpellcheckerSettings {
private SuggestMode suggestMode = SuggestMode.SUGGEST_WHEN_NOT_IN_INDEX;
private float accuracy = 0.5f;
private Suggest.Suggestion.Sort sort = Suggest.Suggestion.Sort.SCORE;
private StringDistance stringDistance = DirectSpellChecker.INTERNAL_LEVENSHTEIN;
private int maxEdits = LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE;
private int maxInspections = 5;
private float maxTermFreq = 0.01f;
private int prefixLength = 1;
private int minWordLength = 4;
private float minDocFreq = 0f;
// NB: If this changes, make sure to change the default in TermBuilderSuggester
public static SuggestMode DEFAULT_SUGGEST_MODE = SuggestMode.SUGGEST_WHEN_NOT_IN_INDEX;
public static float DEFAULT_ACCURACY = 0.5f;
// NB: If this changes, make sure to change the default in TermBuilderSuggester
public static Suggest.Suggestion.Sort DEFAULT_SORT = Suggest.Suggestion.Sort.SCORE;
// NB: If this changes, make sure to change the default in TermBuilderSuggester
public static StringDistance DEFAULT_STRING_DISTANCE = DirectSpellChecker.INTERNAL_LEVENSHTEIN;
public static int DEFAULT_MAX_EDITS = LevenshteinAutomata.MAXIMUM_SUPPORTED_DISTANCE;
public static int DEFAULT_MAX_INSPECTIONS = 5;
public static float DEFAULT_MAX_TERM_FREQ = 0.01f;
public static int DEFAULT_PREFIX_LENGTH = 1;
public static int DEFAULT_MIN_WORD_LENGTH = 4;
public static float DEFAULT_MIN_DOC_FREQ = 0f;
private SuggestMode suggestMode = DEFAULT_SUGGEST_MODE;
private float accuracy = DEFAULT_ACCURACY;
private Suggest.Suggestion.Sort sort = DEFAULT_SORT;
private StringDistance stringDistance = DEFAULT_STRING_DISTANCE;
private int maxEdits = DEFAULT_MAX_EDITS;
private int maxInspections = DEFAULT_MAX_INSPECTIONS;
private float maxTermFreq = DEFAULT_MAX_TERM_FREQ;
private int prefixLength = DEFAULT_PREFIX_LENGTH;
private int minWordLength = DEFAULT_MIN_WORD_LENGTH;
private float minDocFreq = DEFAULT_MIN_DOC_FREQ;
public SuggestMode suggestMode() {
return suggestMode;

View File

@ -19,32 +19,30 @@
package org.elasticsearch.search.suggest;
import org.elasticsearch.action.support.ToXContentToBytes;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Defines how to perform suggesting. This builders allows a number of global options to be specified and
* an arbitrary number of {@link org.elasticsearch.search.suggest.term.TermSuggestionBuilder} instances.
* an arbitrary number of {@link SuggestionBuilder} instances.
* <p>
* Suggesting works by suggesting terms that appear in the suggest text that are similar compared to the terms in
* provided text. These spelling suggestions are based on several options described in this class.
* Suggesting works by suggesting terms/phrases that appear in the suggest text that are similar compared
* to the terms in provided text. These suggestions are based on several options described in this class.
*/
public class SuggestBuilder extends ToXContentToBytes {
public class SuggestBuilder extends ToXContentToBytes implements Writeable<SuggestBuilder> {
private final String name;
private String globalText;
private final List<SuggestionBuilder<?>> suggestions = new ArrayList<>();
public SuggestBuilder() {
this.name = null;
}
public SuggestBuilder(String name) {
this.name = name;
}
/**
@ -54,7 +52,7 @@ public class SuggestBuilder extends ToXContentToBytes {
* The suggest text gets analyzed by the suggest analyzer or the suggest field search analyzer.
* For each analyzed token, suggested terms are suggested if possible.
*/
public SuggestBuilder setText(String globalText) {
public SuggestBuilder setText(@Nullable String globalText) {
this.globalText = globalText;
return this;
}
@ -77,12 +75,7 @@ public class SuggestBuilder extends ToXContentToBytes {
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
if(name == null) {
builder.startObject();
} else {
builder.startObject(name);
}
if (globalText != null) {
builder.field("text", globalText);
}
@ -92,4 +85,45 @@ public class SuggestBuilder extends ToXContentToBytes {
builder.endObject();
return builder;
}
@Override
public SuggestBuilder readFrom(StreamInput in) throws IOException {
final SuggestBuilder builder = new SuggestBuilder();
builder.globalText = in.readOptionalString();
final int size = in.readVInt();
for (int i = 0; i < size; i++) {
builder.suggestions.add(in.readSuggestion());
}
return builder;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeOptionalString(globalText);
final int size = suggestions.size();
out.writeVInt(size);
for (int i = 0; i < size; i++) {
out.writeSuggestion(suggestions.get(i));
}
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {
return false;
}
@SuppressWarnings("unchecked")
SuggestBuilder o = (SuggestBuilder)other;
return Objects.equals(globalText, o.globalText) &&
Objects.equals(suggestions, o.suggestions);
}
@Override
public int hashCode() {
return Objects.hash(globalText, suggestions);
}
}

View File

@ -53,6 +53,7 @@ public abstract class SuggestionBuilder<T extends SuggestionBuilder<T>> extends
protected static final ParseField SHARDSIZE_FIELD = new ParseField("shard_size");
public SuggestionBuilder(String name) {
Objects.requireNonNull(name, "Suggester 'name' cannot be null");
this.name = name;
}
@ -296,4 +297,5 @@ public abstract class SuggestionBuilder<T extends SuggestionBuilder<T>> extends
* HashCode for the subclass of {@link SuggestionBuilder} to implement.
*/
protected abstract int doHashCode();
}

View File

@ -49,9 +49,11 @@ import java.util.Set;
*/
public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSuggestionBuilder> {
public static final CompletionSuggestionBuilder PROTOTYPE = new CompletionSuggestionBuilder("_na_"); // name doesn't matter
final static String SUGGESTION_NAME = "completion";
static final ParseField PAYLOAD_FIELD = new ParseField("payload");
static final ParseField CONTEXTS_FIELD = new ParseField("contexts", "context");
private FuzzyOptionsBuilder fuzzyOptionsBuilder;
private RegexOptionsBuilder regexOptionsBuilder;
private final Map<String, List<ToXContent>> queryContexts = new HashMap<>();

View File

@ -16,13 +16,26 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.suggest.term;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.search.suggest.SuggestionBuilder;
import java.io.IOException;
import java.util.Locale;
import java.util.Objects;
import static org.elasticsearch.search.suggest.DirectSpellcheckerSettings.DEFAULT_ACCURACY;
import static org.elasticsearch.search.suggest.DirectSpellcheckerSettings.DEFAULT_MAX_EDITS;
import static org.elasticsearch.search.suggest.DirectSpellcheckerSettings.DEFAULT_MAX_INSPECTIONS;
import static org.elasticsearch.search.suggest.DirectSpellcheckerSettings.DEFAULT_MAX_TERM_FREQ;
import static org.elasticsearch.search.suggest.DirectSpellcheckerSettings.DEFAULT_MIN_DOC_FREQ;
import static org.elasticsearch.search.suggest.DirectSpellcheckerSettings.DEFAULT_MIN_WORD_LENGTH;
import static org.elasticsearch.search.suggest.DirectSpellcheckerSettings.DEFAULT_PREFIX_LENGTH;
/**
* Defines the actual suggest command. Each command uses the global options
@ -31,18 +44,19 @@ import java.io.IOException;
*/
public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuilder> {
public static final TermSuggestionBuilder PROTOTYPE = new TermSuggestionBuilder("_na_"); // name doesn't matter
static final String SUGGESTION_NAME = "term";
private String suggestMode;
private Float accuracy;
private String sort;
private String stringDistance;
private Integer maxEdits;
private Integer maxInspections;
private Float maxTermFreq;
private Integer prefixLength;
private Integer minWordLength;
private Float minDocFreq;
private SuggestMode suggestMode = SuggestMode.MISSING;
private Float accuracy = DEFAULT_ACCURACY;
private SortBy sort = SortBy.SCORE;
private StringDistanceImpl stringDistance = StringDistanceImpl.INTERNAL;
private Integer maxEdits = DEFAULT_MAX_EDITS;
private Integer maxInspections = DEFAULT_MAX_INSPECTIONS;
private Float maxTermFreq = DEFAULT_MAX_TERM_FREQ;
private Integer prefixLength = DEFAULT_PREFIX_LENGTH;
private Integer minWordLength = DEFAULT_MIN_WORD_LENGTH;
private Float minDocFreq = DEFAULT_MIN_DOC_FREQ;
/**
* @param name
@ -65,11 +79,19 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
* tokens in the suggest text.
* </ol>
*/
public TermSuggestionBuilder suggestMode(String suggestMode) {
public TermSuggestionBuilder suggestMode(SuggestMode suggestMode) {
Objects.requireNonNull(suggestMode, "suggestMode must not be null");
this.suggestMode = suggestMode;
return this;
}
/**
* Get the suggest mode setting.
*/
public SuggestMode suggestMode() {
return suggestMode;
}
/**
* s how similar the suggested terms at least need to be compared to the
* original suggest text tokens. A value between 0 and 1 can be specified.
@ -78,11 +100,21 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
* <p>
* Default is <tt>0.5</tt>
*/
public TermSuggestionBuilder setAccuracy(float accuracy) {
public TermSuggestionBuilder accuracy(float accuracy) {
if (accuracy < 0.0f || accuracy > 1.0f) {
throw new IllegalArgumentException("accuracy must be between 0 and 1");
}
this.accuracy = accuracy;
return this;
}
/**
* Get the accuracy setting.
*/
public Float accuracy() {
return accuracy;
}
/**
* Sets how to sort the suggest terms per suggest text token. Two possible
* values:
@ -90,19 +122,27 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
* <li><code>score</code> - Sort should first be based on score, then
* document frequency and then the term itself.
* <li><code>frequency</code> - Sort should first be based on document
* frequency, then scotr and then the term itself.
* frequency, then score and then the term itself.
* </ol>
* <p>
* What the score is depends on the suggester being used.
*/
public TermSuggestionBuilder sort(String sort) {
public TermSuggestionBuilder sort(SortBy sort) {
Objects.requireNonNull(sort, "sort must not be null");
this.sort = sort;
return this;
}
/**
* Get the sort setting.
*/
public SortBy sort() {
return sort;
}
/**
* Sets what string distance implementation to use for comparing how similar
* suggested terms are. Four possible values can be specified:
* suggested terms are. Five possible values can be specified:
* <ol>
* <li><code>internal</code> - This is the default and is based on
* <code>damerau_levenshtein</code>, but highly optimized for comparing
@ -117,32 +157,60 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
* n-grams.
* </ol>
*/
public TermSuggestionBuilder stringDistance(String stringDistance) {
public TermSuggestionBuilder stringDistance(StringDistanceImpl stringDistance) {
Objects.requireNonNull(stringDistance, "stringDistance must not be null");
this.stringDistance = stringDistance;
return this;
}
/**
* Get the string distance implementation setting.
*/
public StringDistanceImpl stringDistance() {
return stringDistance;
}
/**
* Sets the maximum edit distance candidate suggestions can have in order to
* be considered as a suggestion. Can only be a value between 1 and 2. Any
* other value result in an bad request error being thrown. Defaults to
* <tt>2</tt>.
*/
public TermSuggestionBuilder maxEdits(Integer maxEdits) {
public TermSuggestionBuilder maxEdits(int maxEdits) {
if (maxEdits < 1 || maxEdits > 2) {
throw new IllegalArgumentException("maxEdits must be between 1 and 2");
}
this.maxEdits = maxEdits;
return this;
}
/**
* Get the maximum edit distance setting.
*/
public Integer maxEdits() {
return maxEdits;
}
/**
* A factor that is used to multiply with the size in order to inspect more
* candidate suggestions. Can improve accuracy at the cost of performance.
* Defaults to <tt>5</tt>.
*/
public TermSuggestionBuilder maxInspections(Integer maxInspections) {
public TermSuggestionBuilder maxInspections(int maxInspections) {
if (maxInspections < 0) {
throw new IllegalArgumentException("maxInspections must be positive");
}
this.maxInspections = maxInspections;
return this;
}
/**
* Get the factor for inspecting more candidate suggestions setting.
*/
public Integer maxInspections() {
return maxInspections;
}
/**
* Sets a maximum threshold in number of documents a suggest text token can
* exist in order to be corrected. Can be a relative percentage number (e.g
@ -155,10 +223,23 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
* also improves the suggest performance.
*/
public TermSuggestionBuilder maxTermFreq(float maxTermFreq) {
if (maxTermFreq < 0.0f) {
throw new IllegalArgumentException("maxTermFreq must be positive");
}
if (maxTermFreq > 1.0f && maxTermFreq != Math.floor(maxTermFreq)) {
throw new IllegalArgumentException("if maxTermFreq is greater than 1, it must not be a fraction");
}
this.maxTermFreq = maxTermFreq;
return this;
}
/**
* Get the maximum term frequency threshold setting.
*/
public Float maxTermFreq() {
return maxTermFreq;
}
/**
* Sets the number of minimal prefix characters that must match in order be
* a candidate suggestion. Defaults to 1. Increasing this number improves
@ -166,19 +247,39 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
* terms.
*/
public TermSuggestionBuilder prefixLength(int prefixLength) {
if (prefixLength < 0) {
throw new IllegalArgumentException("prefixLength must be positive");
}
this.prefixLength = prefixLength;
return this;
}
/**
* Get the minimum prefix length that must match setting.
*/
public Integer prefixLength() {
return prefixLength;
}
/**
* The minimum length a suggest text term must have in order to be
* corrected. Defaults to <tt>4</tt>.
*/
public TermSuggestionBuilder minWordLength(int minWordLength) {
if (minWordLength < 1) {
throw new IllegalArgumentException("minWordLength must be greater or equal to 1");
}
this.minWordLength = minWordLength;
return this;
}
/**
* Get the minimum length of a text term to be corrected setting.
*/
public Integer minWordLength() {
return minWordLength;
}
/**
* Sets a minimal threshold in number of documents a suggested term should
* appear in. This can be specified as an absolute number or as a relative
@ -187,10 +288,24 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
* value higher than 1 is specified then the number cannot be fractional.
*/
public TermSuggestionBuilder minDocFreq(float minDocFreq) {
if (minDocFreq < 0.0f) {
throw new IllegalArgumentException("minDocFreq must be positive");
}
if (minDocFreq > 1.0f && minDocFreq != Math.floor(minDocFreq)) {
throw new IllegalArgumentException("if minDocFreq is greater than 1, it must not be a fraction");
}
this.minDocFreq = minDocFreq;
return this;
}
/**
* Get the minimal threshold for the frequency of a term appearing in the
* document set setting.
*/
public Float minDocFreq() {
return minDocFreq;
}
@Override
public XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws IOException {
if (suggestMode != null) {
@ -233,25 +348,149 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
@Override
public void doWriteTo(StreamOutput out) throws IOException {
// NORELEASE
throw new UnsupportedOperationException();
suggestMode.writeTo(out);
out.writeFloat(accuracy);
sort.writeTo(out);
stringDistance.writeTo(out);
out.writeVInt(maxEdits);
out.writeVInt(maxInspections);
out.writeFloat(maxTermFreq);
out.writeVInt(prefixLength);
out.writeVInt(minWordLength);
out.writeFloat(minDocFreq);
}
@Override
public TermSuggestionBuilder doReadFrom(StreamInput in, String name) throws IOException {
// NORELEASE
throw new UnsupportedOperationException();
TermSuggestionBuilder builder = new TermSuggestionBuilder(name);
builder.suggestMode = SuggestMode.PROTOTYPE.readFrom(in);
builder.accuracy = in.readFloat();
builder.sort = SortBy.PROTOTYPE.readFrom(in);
builder.stringDistance = StringDistanceImpl.PROTOTYPE.readFrom(in);
builder.maxEdits = in.readVInt();
builder.maxInspections = in.readVInt();
builder.maxTermFreq = in.readFloat();
builder.prefixLength = in.readVInt();
builder.minWordLength = in.readVInt();
builder.minDocFreq = in.readFloat();
return builder;
}
@Override
protected boolean doEquals(TermSuggestionBuilder other) {
// NORELEASE
return false;
return Objects.equals(suggestMode, other.suggestMode) &&
Objects.equals(accuracy, other.accuracy) &&
Objects.equals(sort, other.sort) &&
Objects.equals(stringDistance, other.stringDistance) &&
Objects.equals(maxEdits, other.maxEdits) &&
Objects.equals(maxInspections, other.maxInspections) &&
Objects.equals(maxTermFreq, other.maxTermFreq) &&
Objects.equals(prefixLength, other.prefixLength) &&
Objects.equals(minWordLength, other.minWordLength) &&
Objects.equals(minDocFreq, other.minDocFreq);
}
@Override
protected int doHashCode() {
// NORELEASE
return 0;
return Objects.hash(suggestMode, accuracy, sort, stringDistance, maxEdits, maxInspections,
maxTermFreq, prefixLength, minWordLength, minDocFreq);
}
/** An enum representing the valid suggest modes. */
public enum SuggestMode implements Writeable<SuggestMode> {
/** Only suggest terms in the suggest text that aren't in the index. This is the default. */
MISSING,
/** Only suggest terms that occur in more docs then the original suggest text term. */
POPULAR,
/** Suggest any matching suggest terms based on tokens in the suggest text. */
ALWAYS;
protected static SuggestMode PROTOTYPE = MISSING;
@Override
public void writeTo(final StreamOutput out) throws IOException {
out.writeVInt(ordinal());
}
@Override
public SuggestMode readFrom(final StreamInput in) throws IOException {
int ordinal = in.readVInt();
if (ordinal < 0 || ordinal >= values().length) {
throw new IOException("Unknown SuggestMode ordinal [" + ordinal + "]");
}
return values()[ordinal];
}
public static SuggestMode fromString(final String str) {
Objects.requireNonNull(str, "Input string is null");
return valueOf(str.toUpperCase(Locale.ROOT));
}
}
/** An enum representing the valid sorting options */
public enum SortBy implements Writeable<SortBy> {
/** Sort should first be based on score, then document frequency and then the term itself. */
SCORE,
/** Sort should first be based on document frequency, then score and then the term itself. */
FREQUENCY;
protected static SortBy PROTOTYPE = SCORE;
@Override
public void writeTo(final StreamOutput out) throws IOException {
out.writeVInt(ordinal());
}
@Override
public SortBy readFrom(final StreamInput in) throws IOException {
int ordinal = in.readVInt();
if (ordinal < 0 || ordinal >= values().length) {
throw new IOException("Unknown SortBy ordinal [" + ordinal + "]");
}
return values()[ordinal];
}
public static SortBy fromString(final String str) {
Objects.requireNonNull(str, "Input string is null");
return valueOf(str.toUpperCase(Locale.ROOT));
}
}
/** An enum representing the valid string edit distance algorithms for determining suggestions. */
public enum StringDistanceImpl implements Writeable<StringDistanceImpl> {
/** This is the default and is based on <code>damerau_levenshtein</code>, but highly optimized
* for comparing string distance for terms inside the index. */
INTERNAL,
/** String distance algorithm based on Damerau-Levenshtein algorithm. */
DAMERAU_LEVENSHTEIN,
/** String distance algorithm based on Levenstein edit distance algorithm. */
LEVENSTEIN,
/** String distance algorithm based on Jaro-Winkler algorithm. */
JAROWINKLER,
/** String distance algorithm based on character n-grams. */
NGRAM;
protected static StringDistanceImpl PROTOTYPE = INTERNAL;
@Override
public void writeTo(final StreamOutput out) throws IOException {
out.writeVInt(ordinal());
}
@Override
public StringDistanceImpl readFrom(final StreamInput in) throws IOException {
int ordinal = in.readVInt();
if (ordinal < 0 || ordinal >= values().length) {
throw new IOException("Unknown StringDistanceImpl ordinal [" + ordinal + "]");
}
return values()[ordinal];
}
public static StringDistanceImpl fromString(final String str) {
Objects.requireNonNull(str, "Input string is null");
return valueOf(str.toUpperCase(Locale.ROOT));
}
}
}

View File

@ -0,0 +1,74 @@
/*
* 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.common.io.stream;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import static org.hamcrest.Matchers.equalTo;
/**
* Abstract class offering base functionality for testing @{link Writeable} enums.
*/
public abstract class AbstractWriteableEnumTestCase extends ESTestCase {
/**
* Test that the ordinals for the enum are consistent (i.e. the order hasn't changed)
* because writing an enum to a stream often uses the ordinal value.
*/
public abstract void testValidOrdinals();
/**
* Test that the conversion from a string to enum is correct.
*/
public abstract void testFromString();
/**
* Test that the correct enum value is produced from the serialized value in the {@link StreamInput}.
*/
public abstract void testReadFrom() throws IOException;
/**
* Test that the correct serialized value is produced from the {@link StreamOutput}.
*/
public abstract void testWriteTo() throws IOException;
// a convenience method for testing the write of a writeable enum
protected static void assertWriteToStream(final Writeable writeableEnum, final int ordinal) throws IOException {
try (BytesStreamOutput out = new BytesStreamOutput()) {
writeableEnum.writeTo(out);
try (StreamInput in = StreamInput.wrap(out.bytes())) {
assertThat(in.readVInt(), equalTo(ordinal));
}
}
}
// a convenience method for testing the read of a writeable enum
protected static <T extends Writeable<T>> void assertReadFromStream(final int ordinal, final Writeable<T> expected) throws IOException {
try (BytesStreamOutput out = new BytesStreamOutput()) {
out.writeVInt(ordinal);
try (StreamInput in = StreamInput.wrap(out.bytes())) {
assertThat(expected.readFrom(in), equalTo(expected));
}
}
}
}

View File

@ -23,7 +23,9 @@ import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.NamedWriteableAwareStreamInput;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder;
import org.elasticsearch.search.suggest.term.TermSuggestionBuilder;
import org.elasticsearch.test.ESTestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
@ -46,7 +48,9 @@ public abstract class AbstractSuggestionBuilderTestCase<SB extends SuggestionBui
@BeforeClass
public static void init() {
namedWriteableRegistry = new NamedWriteableRegistry();
namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, TermSuggestionBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, PhraseSuggestionBuilder.PROTOTYPE);
namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, CompletionSuggestionBuilder.PROTOTYPE);
}
@AfterClass

View File

@ -0,0 +1,70 @@
/*
* 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.search.suggest.term;
import org.elasticsearch.common.io.stream.AbstractWriteableEnumTestCase;
import java.io.IOException;
import static org.elasticsearch.search.suggest.term.TermSuggestionBuilder.SortBy;
import static org.hamcrest.Matchers.equalTo;
/**
* Test the {@link SortBy} enum.
*/
public class SortByTests extends AbstractWriteableEnumTestCase {
@Override
public void testValidOrdinals() {
assertThat(SortBy.SCORE.ordinal(), equalTo(0));
assertThat(SortBy.FREQUENCY.ordinal(), equalTo(1));
}
@Override
public void testFromString() {
assertThat(SortBy.fromString("score"), equalTo(SortBy.SCORE));
assertThat(SortBy.fromString("frequency"), equalTo(SortBy.FREQUENCY));
final String doesntExist = "doesnt_exist";
try {
SortBy.fromString(doesntExist);
fail("SortBy should not have an element " + doesntExist);
} catch (IllegalArgumentException e) {
}
try {
SortBy.fromString(null);
fail("SortBy.fromString on a null value should throw an exception.");
} catch (NullPointerException e) {
assertThat(e.getMessage(), equalTo("Input string is null"));
}
}
@Override
public void testWriteTo() throws IOException {
assertWriteToStream(SortBy.SCORE, 0);
assertWriteToStream(SortBy.FREQUENCY, 1);
}
@Override
public void testReadFrom() throws IOException {
assertReadFromStream(0, SortBy.SCORE);
assertReadFromStream(1, SortBy.FREQUENCY);
}
}

View File

@ -0,0 +1,82 @@
/*
* 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.search.suggest.term;
import org.elasticsearch.common.io.stream.AbstractWriteableEnumTestCase;
import java.io.IOException;
import static org.elasticsearch.search.suggest.term.TermSuggestionBuilder.StringDistanceImpl;
import static org.hamcrest.Matchers.equalTo;
/**
* Test for the {@link StringDistanceImpl} enum.
*/
public class StringDistanceImplTests extends AbstractWriteableEnumTestCase {
@Override
public void testValidOrdinals() {
assertThat(StringDistanceImpl.INTERNAL.ordinal(), equalTo(0));
assertThat(StringDistanceImpl.DAMERAU_LEVENSHTEIN.ordinal(), equalTo(1));
assertThat(StringDistanceImpl.LEVENSTEIN.ordinal(), equalTo(2));
assertThat(StringDistanceImpl.JAROWINKLER.ordinal(), equalTo(3));
assertThat(StringDistanceImpl.NGRAM.ordinal(), equalTo(4));
}
@Override
public void testFromString() {
assertThat(StringDistanceImpl.fromString("internal"), equalTo(StringDistanceImpl.INTERNAL));
assertThat(StringDistanceImpl.fromString("damerau_levenshtein"), equalTo(StringDistanceImpl.DAMERAU_LEVENSHTEIN));
assertThat(StringDistanceImpl.fromString("levenstein"), equalTo(StringDistanceImpl.LEVENSTEIN));
assertThat(StringDistanceImpl.fromString("jarowinkler"), equalTo(StringDistanceImpl.JAROWINKLER));
assertThat(StringDistanceImpl.fromString("ngram"), equalTo(StringDistanceImpl.NGRAM));
final String doesntExist = "doesnt_exist";
try {
StringDistanceImpl.fromString(doesntExist);
fail("StringDistanceImpl should not have an element " + doesntExist);
} catch (IllegalArgumentException e) {
}
try {
StringDistanceImpl.fromString(null);
fail("StringDistanceImpl.fromString on a null value should throw an exception.");
} catch (NullPointerException e) {
assertThat(e.getMessage(), equalTo("Input string is null"));
}
}
@Override
public void testWriteTo() throws IOException {
assertWriteToStream(StringDistanceImpl.INTERNAL, 0);
assertWriteToStream(StringDistanceImpl.DAMERAU_LEVENSHTEIN, 1);
assertWriteToStream(StringDistanceImpl.LEVENSTEIN, 2);
assertWriteToStream(StringDistanceImpl.JAROWINKLER, 3);
assertWriteToStream(StringDistanceImpl.NGRAM, 4);
}
@Override
public void testReadFrom() throws IOException {
assertReadFromStream(0, StringDistanceImpl.INTERNAL);
assertReadFromStream(1, StringDistanceImpl.DAMERAU_LEVENSHTEIN);
assertReadFromStream(2, StringDistanceImpl.LEVENSTEIN);
assertReadFromStream(3, StringDistanceImpl.JAROWINKLER);
assertReadFromStream(4, StringDistanceImpl.NGRAM);
}
}

View File

@ -0,0 +1,74 @@
/*
* 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.search.suggest.term;
import org.elasticsearch.common.io.stream.AbstractWriteableEnumTestCase;
import java.io.IOException;
import static org.elasticsearch.search.suggest.term.TermSuggestionBuilder.SuggestMode;
import static org.hamcrest.Matchers.equalTo;
/**
* Test the {@link SuggestMode} enum.
*/
public class SuggestModeTests extends AbstractWriteableEnumTestCase {
@Override
public void testValidOrdinals() {
assertThat(SuggestMode.MISSING.ordinal(), equalTo(0));
assertThat(SuggestMode.POPULAR.ordinal(), equalTo(1));
assertThat(SuggestMode.ALWAYS.ordinal(), equalTo(2));
}
@Override
public void testFromString() {
assertThat(SuggestMode.fromString("missing"), equalTo(SuggestMode.MISSING));
assertThat(SuggestMode.fromString("popular"), equalTo(SuggestMode.POPULAR));
assertThat(SuggestMode.fromString("always"), equalTo(SuggestMode.ALWAYS));
final String doesntExist = "doesnt_exist";
try {
SuggestMode.fromString(doesntExist);
fail("SuggestMode should not have an element " + doesntExist);
} catch (IllegalArgumentException e) {
}
try {
SuggestMode.fromString(null);
fail("SuggestMode.fromString on a null value should throw an exception.");
} catch (NullPointerException e) {
assertThat(e.getMessage(), equalTo("Input string is null"));
}
}
@Override
public void testWriteTo() throws IOException {
assertWriteToStream(SuggestMode.MISSING, 0);
assertWriteToStream(SuggestMode.POPULAR, 1);
assertWriteToStream(SuggestMode.ALWAYS, 2);
}
@Override
public void testReadFrom() throws IOException {
assertReadFromStream(0, SuggestMode.MISSING);
assertReadFromStream(1, SuggestMode.POPULAR);
assertReadFromStream(2, SuggestMode.ALWAYS);
}
}

View File

@ -0,0 +1,248 @@
/*
* 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.search.suggest.term;
import org.elasticsearch.search.suggest.AbstractSuggestionBuilderTestCase;
import java.io.IOException;
import static org.elasticsearch.search.suggest.term.TermSuggestionBuilder.SortBy;
import static org.elasticsearch.search.suggest.term.TermSuggestionBuilder.StringDistanceImpl;
import static org.elasticsearch.search.suggest.term.TermSuggestionBuilder.SuggestMode;
import static org.hamcrest.Matchers.notNullValue;
/**
* Test the {@link TermSuggestionBuilder} class.
*/
public class TermSuggestionBuilderTests extends AbstractSuggestionBuilderTestCase<TermSuggestionBuilder> {
@Override
protected TermSuggestionBuilder randomSuggestionBuilder() {
TermSuggestionBuilder testBuilder = new TermSuggestionBuilder(randomAsciiOfLength(10));
maybeSet(testBuilder::suggestMode, randomSuggestMode());
maybeSet(testBuilder::accuracy, randomFloat());
maybeSet(testBuilder::sort, randomSort());
maybeSet(testBuilder::stringDistance, randomStringDistance());
maybeSet(testBuilder::maxEdits, randomIntBetween(1, 2));
maybeSet(testBuilder::maxInspections, randomInt(Integer.MAX_VALUE));
maybeSet(testBuilder::maxTermFreq, randomFloat());
maybeSet(testBuilder::prefixLength, randomInt(Integer.MAX_VALUE));
maybeSet(testBuilder::minWordLength, randomInt(Integer.MAX_VALUE));
maybeSet(testBuilder::minDocFreq, randomFloat());
return testBuilder;
}
private SuggestMode randomSuggestMode() {
final int randomVal = randomIntBetween(0, 2);
switch (randomVal) {
case 0: return SuggestMode.MISSING;
case 1: return SuggestMode.POPULAR;
case 2: return SuggestMode.ALWAYS;
default: throw new IllegalArgumentException("No suggest mode with an ordinal of " + randomVal);
}
}
private SortBy randomSort() {
int randomVal = randomIntBetween(0, 1);
switch (randomVal) {
case 0: return SortBy.SCORE;
case 1: return SortBy.FREQUENCY;
default: throw new IllegalArgumentException("No sort mode with an ordinal of " + randomVal);
}
}
private StringDistanceImpl randomStringDistance() {
int randomVal = randomIntBetween(0, 4);
switch (randomVal) {
case 0: return StringDistanceImpl.INTERNAL;
case 1: return StringDistanceImpl.DAMERAU_LEVENSHTEIN;
case 2: return StringDistanceImpl.LEVENSTEIN;
case 3: return StringDistanceImpl.JAROWINKLER;
case 4: return StringDistanceImpl.NGRAM;
default: throw new IllegalArgumentException("No string distance algorithm with an ordinal of " + randomVal);
}
}
@Override
protected void mutateSpecificParameters(TermSuggestionBuilder builder) throws IOException {
switch (randomIntBetween(0, 9)) {
case 0:
builder.suggestMode(randomValueOtherThan(builder.suggestMode(), () -> randomSuggestMode()));
break;
case 1:
builder.accuracy(randomValueOtherThan(builder.accuracy(), () -> randomFloat()));
break;
case 2:
builder.sort(randomValueOtherThan(builder.sort(), () -> randomSort()));
break;
case 3:
builder.stringDistance(randomValueOtherThan(builder.stringDistance(), () -> randomStringDistance()));
break;
case 4:
builder.maxEdits(randomValueOtherThan(builder.maxEdits(), () -> randomIntBetween(1, 2)));
break;
case 5:
builder.maxInspections(randomValueOtherThan(builder.maxInspections(), () -> randomInt(Integer.MAX_VALUE)));
break;
case 6:
builder.maxTermFreq(randomValueOtherThan(builder.maxTermFreq(), () -> randomFloat()));
break;
case 7:
builder.prefixLength(randomValueOtherThan(builder.prefixLength(), () -> randomInt(Integer.MAX_VALUE)));
break;
case 8:
builder.minWordLength(randomValueOtherThan(builder.minWordLength(), () -> randomInt(Integer.MAX_VALUE)));
break;
case 9:
builder.minDocFreq(randomValueOtherThan(builder.minDocFreq(), () -> randomFloat()));
break;
default:
break; // do nothing
}
}
public void testInvalidParameters() throws IOException {
TermSuggestionBuilder builder = new TermSuggestionBuilder(randomAsciiOfLength(10));
// test invalid accuracy values
try {
builder.accuracy(-0.5f);
fail("Should not allow accuracy to be set to a negative value.");
} catch (IllegalArgumentException e) {
}
try {
builder.accuracy(1.1f);
fail("Should not allow accuracy to be greater than 1.0.");
} catch (IllegalArgumentException e) {
}
// test invalid max edit distance values
try {
builder.maxEdits(0);
fail("Should not allow maxEdits to be less than 1.");
} catch (IllegalArgumentException e) {
}
try {
builder.maxEdits(-1);
fail("Should not allow maxEdits to be a negative value.");
} catch (IllegalArgumentException e) {
}
try {
builder.maxEdits(3);
fail("Should not allow maxEdits to be greater than 2.");
} catch (IllegalArgumentException e) {
}
// test invalid max inspections values
try {
builder.maxInspections(-1);
fail("Should not allow maxInspections to be a negative value.");
} catch (IllegalArgumentException e) {
}
// test invalid max term freq values
try {
builder.maxTermFreq(-0.5f);
fail("Should not allow max term freq to be a negative value.");
} catch (IllegalArgumentException e) {
}
try {
builder.maxTermFreq(1.5f);
fail("If max term freq is greater than 1, it must be a whole number.");
} catch (IllegalArgumentException e) {
}
try {
builder.maxTermFreq(2.0f); // this should be allowed
} catch (IllegalArgumentException e) {
fail("A max term freq greater than 1 that is a whole number should be allowed.");
}
// test invalid min doc freq values
try {
builder.minDocFreq(-0.5f);
fail("Should not allow min doc freq to be a negative value.");
} catch (IllegalArgumentException e) {
}
try {
builder.minDocFreq(1.5f);
fail("If min doc freq is greater than 1, it must be a whole number.");
} catch (IllegalArgumentException e) {
}
try {
builder.minDocFreq(2.0f); // this should be allowed
} catch (IllegalArgumentException e) {
fail("A min doc freq greater than 1 that is a whole number should be allowed.");
}
// test invalid min word length values
try {
builder.minWordLength(0);
fail("A min word length < 1 should not be allowed.");
} catch (IllegalArgumentException e) {
}
try {
builder.minWordLength(-1);
fail("Should not allow min word length to be a negative value.");
} catch (IllegalArgumentException e) {
}
// test invalid prefix length values
try {
builder.prefixLength(-1);
fail("Should not allow prefix length to be a negative value.");
} catch (IllegalArgumentException e) {
}
// test invalid size values
try {
builder.size(0);
fail("Size must be a positive value.");
} catch (IllegalArgumentException e) {
}
try {
builder.size(-1);
fail("Size must be a positive value.");
} catch (IllegalArgumentException e) {
}
// null values not allowed for enums
try {
builder.sort(null);
fail("Should not allow setting a null sort value.");
} catch (NullPointerException e) {
}
try {
builder.stringDistance(null);
fail("Should not allow setting a null string distance value.");
} catch (NullPointerException e) {
}
try {
builder.suggestMode(null);
fail("Should not allow setting a null suggest mode value.");
} catch (NullPointerException e) {
}
}
public void testDefaultValuesSet() {
TermSuggestionBuilder builder = new TermSuggestionBuilder(randomAsciiOfLength(10));
assertThat(builder.accuracy(), notNullValue());
assertThat(builder.maxEdits(), notNullValue());
assertThat(builder.maxInspections(), notNullValue());
assertThat(builder.maxTermFreq(), notNullValue());
assertThat(builder.minDocFreq(), notNullValue());
assertThat(builder.minWordLength(), notNullValue());
assertThat(builder.prefixLength(), notNullValue());
assertThat(builder.sort(), notNullValue());
assertThat(builder.stringDistance(), notNullValue());
assertThat(builder.suggestMode(), notNullValue());
}
}

View File

@ -27,6 +27,8 @@ import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.search.suggest.SuggestBuilders.phraseSuggestion;
import static org.elasticsearch.search.suggest.SuggestBuilders.termSuggestion;
import static org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder.candidateGenerator;
import static org.elasticsearch.search.suggest.SuggestionBuilder.SortBy;
import static org.elasticsearch.search.suggest.SuggestionBuilder.SuggestMode;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSuggestion;
@ -100,7 +102,7 @@ public class SuggestSearchTests extends ESIntegTestCase {
refresh();
TermSuggestionBuilder termSuggest = termSuggestion("test")
.suggestMode("always") // Always, otherwise the results can vary between requests.
.suggestMode(SuggestMode.ALWAYS) // Always, otherwise the results can vary between requests.
.text("abcd")
.field("text");
logger.info("--> run suggestions with one index");
@ -114,7 +116,7 @@ public class SuggestSearchTests extends ESIntegTestCase {
index("test_1", "type1", "4", "text", "ab cc");
refresh();
termSuggest = termSuggestion("test")
.suggestMode("always") // Always, otherwise the results can vary between requests.
.suggestMode(SuggestMode.ALWAYS) // Always, otherwise the results can vary between requests.
.text("ab cd")
.minWordLength(1)
.field("text");
@ -141,7 +143,7 @@ public class SuggestSearchTests extends ESIntegTestCase {
refresh();
termSuggest = termSuggestion("test")
.suggestMode("always") // Always, otherwise the results can vary between requests.
.suggestMode(SuggestMode.ALWAYS) // Always, otherwise the results can vary between requests.
.text("ab cd")
.minWordLength(1)
.field("text");
@ -161,7 +163,7 @@ public class SuggestSearchTests extends ESIntegTestCase {
termSuggest = termSuggestion("test")
.suggestMode("always") // Always, otherwise the results can vary between requests.
.suggestMode(SuggestMode.ALWAYS) // Always, otherwise the results can vary between requests.
.text("ABCD")
.minWordLength(1)
.field("text");
@ -241,7 +243,7 @@ public class SuggestSearchTests extends ESIntegTestCase {
assertThat("didn't ask for suggestions but got some", search.getSuggest(), nullValue());
TermSuggestionBuilder termSuggestion = termSuggestion("test")
.suggestMode("always") // Always, otherwise the results can vary between requests.
.suggestMode(SuggestMode.ALWAYS) // Always, otherwise the results can vary between requests.
.text("abcd")
.field("text")
.size(10);
@ -316,7 +318,7 @@ public class SuggestSearchTests extends ESIntegTestCase {
assertThat("didn't ask for suggestions but got some", search.getSuggest(), nullValue());
TermSuggestionBuilder termSuggest = termSuggestion("test")
.suggestMode("always") // Always, otherwise the results can vary between requests.
.suggestMode(SuggestMode.ALWAYS) // Always, otherwise the results can vary between requests.
.text("abcd")
.field("text");
Suggest suggest = searchSuggest( termSuggest);
@ -336,7 +338,7 @@ public class SuggestSearchTests extends ESIntegTestCase {
refresh();
TermSuggestionBuilder termSuggest = termSuggestion("test")
.suggestMode("always") // Always, otherwise the results can vary between requests.
.suggestMode(SuggestMode.ALWAYS) // Always, otherwise the results can vary between requests.
.text("abcd")
.field("text");
Suggest suggest = searchSuggest( termSuggest);
@ -361,13 +363,13 @@ public class SuggestSearchTests extends ESIntegTestCase {
Suggest suggest = searchSuggest(
termSuggestion("size1")
.size(1).text("prefix_abcd").maxTermFreq(10).prefixLength(1).minDocFreq(0)
.field("field1").suggestMode("always"),
.field("field1").suggestMode(SuggestMode.ALWAYS),
termSuggestion("field2")
.field("field2").text("prefix_eeeh prefix_efgh")
.maxTermFreq(10).minDocFreq(0).suggestMode("always"),
.maxTermFreq(10).minDocFreq(0).suggestMode(SuggestMode.ALWAYS),
termSuggestion("accuracy")
.field("field2").text("prefix_efgh").setAccuracy(1f)
.maxTermFreq(10).minDocFreq(0).suggestMode("always"));
.field("field2").text("prefix_efgh").accuracy(1f)
.maxTermFreq(10).minDocFreq(0).suggestMode(SuggestMode.ALWAYS));
assertSuggestion(suggest, 0, "size1", "prefix_aacd");
assertThat(suggest.getSuggestion("field2").getEntries().get(0).getText().string(), equalTo("prefix_eeeh"));
assertSuggestion(suggest, 0, "field2", "prefix_efgh");
@ -403,15 +405,15 @@ public class SuggestSearchTests extends ESIntegTestCase {
Suggest suggest = searchSuggest( "prefix_abcd",
termSuggestion("size3SortScoreFirst")
.size(3).minDocFreq(0).field("field1").suggestMode("always"),
.size(3).minDocFreq(0).field("field1").suggestMode(SuggestMode.ALWAYS),
termSuggestion("size10SortScoreFirst")
.size(10).minDocFreq(0).field("field1").suggestMode("always").shardSize(50),
.size(10).minDocFreq(0).field("field1").suggestMode(SuggestMode.ALWAYS).shardSize(50),
termSuggestion("size3SortScoreFirstMaxEdits1")
.maxEdits(1)
.size(10).minDocFreq(0).field("field1").suggestMode("always"),
.size(10).minDocFreq(0).field("field1").suggestMode(SuggestMode.ALWAYS),
termSuggestion("size10SortFrequencyFirst")
.size(10).sort("frequency").shardSize(1000)
.minDocFreq(0).field("field1").suggestMode("always"));
.size(10).sort(SortBy.FREQUENCY).shardSize(1000)
.minDocFreq(0).field("field1").suggestMode(SuggestMode.ALWAYS));
// The commented out assertions fail sometimes because suggestions are based off of shard frequencies instead of index frequencies.
assertSuggestion(suggest, 0, "size3SortScoreFirst", "prefix_aacd", "prefix_abcc", "prefix_accd");
@ -784,7 +786,7 @@ public class SuggestSearchTests extends ESIntegTestCase {
Suggest suggest = searchSuggest( "foobar",
termSuggestion("simple")
.size(10).minDocFreq(0).field("field1").suggestMode("always"));
.size(10).minDocFreq(0).field("field1").suggestMode(SuggestMode.ALWAYS));
ElasticsearchAssertions.assertSuggestionSize(suggest, 0, 3, "simple");
}