summaryrefslogtreecommitdiff
path: root/core/src/main/java
diff options
context:
space:
mode:
authorNik Everett <nik9000@gmail.com>2016-03-28 11:06:03 -0400
committerNik Everett <nik9000@gmail.com>2016-03-29 17:55:01 -0400
commitdf08854c60a2bf1402377615e9bce644e6304e0b (patch)
treeba5090acaadd0bcc09069f2a94c417117151d49f /core/src/main/java
parent101a32573c0eeb3abe70cc1ead569b719ddbef75 (diff)
Remove PROTOTYPEs from suggesters
Also stops using guice for suggesters at all and lots of checkstyle.
Diffstat (limited to 'core/src/main/java')
-rw-r--r--core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java13
-rw-r--r--core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java13
-rw-r--r--core/src/main/java/org/elasticsearch/common/io/stream/Writeable.java8
-rw-r--r--core/src/main/java/org/elasticsearch/search/SearchModule.java22
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/SortBy.java5
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/Suggester.java8
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/Suggesters.java54
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java70
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java15
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java76
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java2
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java48
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java36
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryContextMapping.java4
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java6
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/context/ContextMapping.java8
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java4
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java6
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/context/QueryContext.java33
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGenerator.java40
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java103
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java31
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/LaplaceScorer.java12
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpoatingScorer.java4
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java41
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java14
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java152
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionContext.java8
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java8
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java31
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoffScorer.java9
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java22
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestion.java2
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java76
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionContext.java2
35 files changed, 453 insertions, 533 deletions
diff --git a/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java b/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java
index a5750fcc54..11c904c8b7 100644
--- a/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java
+++ b/core/src/main/java/org/elasticsearch/common/io/stream/StreamInput.java
@@ -116,6 +116,19 @@ public abstract class StreamInput extends InputStream {
}
/**
+ * Reads an optional bytes reference from this stream. It might hold an actual reference to the underlying bytes of the stream. Use this
+ * only if you must differentiate null from empty. Use {@link StreamInput#readBytesReference()} and
+ * {@link StreamOutput#writeBytesReference(BytesReference)} if you do not.
+ */
+ public BytesReference readOptionalBytesReference() throws IOException {
+ int length = readVInt() - 1;
+ if (length < 0) {
+ return null;
+ }
+ return readBytesReference(length);
+ }
+
+ /**
* Reads a bytes reference from this stream, might hold an actual reference to the underlying
* bytes of the stream.
*/
diff --git a/core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java b/core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java
index 6b7607a3e7..55e45e8baa 100644
--- a/core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java
+++ b/core/src/main/java/org/elasticsearch/common/io/stream/StreamOutput.java
@@ -146,6 +146,19 @@ public abstract class StreamOutput extends OutputStream {
bytes.writeTo(this);
}
+ /**
+ * Writes an optional bytes reference including a length header. Use this if you need to differentiate between null and empty bytes
+ * references. Use {@link #writeBytesReference(BytesReference)} and {@link StreamInput#readBytesReference()} if you do not.
+ */
+ public void writeOptionalBytesReference(@Nullable BytesReference bytes) throws IOException {
+ if (bytes == null) {
+ writeVInt(0);
+ return;
+ }
+ writeVInt(bytes.length() + 1);
+ bytes.writeTo(this);
+ }
+
public void writeBytesRef(BytesRef bytes) throws IOException {
if (bytes == null) {
writeVInt(0);
diff --git a/core/src/main/java/org/elasticsearch/common/io/stream/Writeable.java b/core/src/main/java/org/elasticsearch/common/io/stream/Writeable.java
index 75c1f28c39..6ebe1b3b99 100644
--- a/core/src/main/java/org/elasticsearch/common/io/stream/Writeable.java
+++ b/core/src/main/java/org/elasticsearch/common/io/stream/Writeable.java
@@ -46,7 +46,8 @@ public interface Writeable<T> extends StreamableReader<T> { // TODO remove exten
@Override
default T readFrom(StreamInput in) throws IOException {
// See class javadoc for reasoning
- throw new UnsupportedOperationException("Prefer calling a constructor that takes a StreamInput to calling readFrom.");
+ throw new UnsupportedOperationException(
+ "Prefer calling a constructor or static method that takes a StreamInput to calling readFrom.");
}
/**
@@ -56,6 +57,9 @@ public interface Writeable<T> extends StreamableReader<T> { // TODO remove exten
*/
@FunctionalInterface
interface Reader<R> {
- R read(StreamInput t) throws IOException;
+ /**
+ * Read R from a stream.
+ */
+ R read(StreamInput in) throws IOException;
}
}
diff --git a/core/src/main/java/org/elasticsearch/search/SearchModule.java b/core/src/main/java/org/elasticsearch/search/SearchModule.java
index 8756a31c44..1b69a155e1 100644
--- a/core/src/main/java/org/elasticsearch/search/SearchModule.java
+++ b/core/src/main/java/org/elasticsearch/search/SearchModule.java
@@ -249,7 +249,7 @@ public class SearchModule extends AbstractModule {
private final Set<Aggregator.Parser> aggParsers = new HashSet<>();
private final Set<PipelineAggregator.Parser> pipelineAggParsers = new HashSet<>();
private final Highlighters highlighters = new Highlighters();
- private final Suggesters suggesters = new Suggesters();
+ private final Suggesters suggesters;
/**
* Function score parsers constructed on registration. This is ok because
* they don't have any dependencies.
@@ -274,6 +274,7 @@ public class SearchModule extends AbstractModule {
public SearchModule(Settings settings, NamedWriteableRegistry namedWriteableRegistry) {
this.settings = settings;
this.namedWriteableRegistry = namedWriteableRegistry;
+ suggesters = new Suggesters(namedWriteableRegistry);
registerBuiltinFunctionScoreParsers();
registerBuiltinQueryParsers();
@@ -286,8 +287,7 @@ public class SearchModule extends AbstractModule {
}
public void registerSuggester(String key, Suggester<?> suggester) {
- suggesters.registerExtension(key, suggester.getClass());
- namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, suggester.getBuilderPrototype());
+ suggesters.register(key, suggester);
}
/**
@@ -337,10 +337,10 @@ public class SearchModule extends AbstractModule {
protected void configure() {
IndicesQueriesRegistry indicesQueriesRegistry = buildQueryParserRegistry();
bind(IndicesQueriesRegistry.class).toInstance(indicesQueriesRegistry);
+ bind(Suggesters.class).toInstance(suggesters);
configureSearch();
configureAggs(indicesQueriesRegistry);
configureHighlighters();
- configureSuggesters();
configureFetchSubPhase();
configureShapes();
}
@@ -378,16 +378,6 @@ public class SearchModule extends AbstractModule {
return new IndicesQueriesRegistry(settings, queryParsersMap);
}
- protected void configureSuggesters() {
- suggesters.bind(binder());
- namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, TermSuggestionBuilder.PROTOTYPE);
- namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, PhraseSuggestionBuilder.PROTOTYPE);
- namedWriteableRegistry.registerPrototype(SuggestionBuilder.class, CompletionSuggestionBuilder.PROTOTYPE);
- namedWriteableRegistry.registerPrototype(SmoothingModel.class, Laplace.PROTOTYPE);
- namedWriteableRegistry.registerPrototype(SmoothingModel.class, LinearInterpolation.PROTOTYPE);
- namedWriteableRegistry.registerPrototype(SmoothingModel.class, StupidBackoff.PROTOTYPE);
- }
-
protected void configureHighlighters() {
highlighters.bind(binder());
}
@@ -615,4 +605,8 @@ public class SearchModule extends AbstractModule {
BucketSelectorPipelineAggregator.registerStreams();
SerialDiffPipelineAggregator.registerStreams();
}
+
+ public Suggesters getSuggesters() {
+ return suggesters;
+ }
}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/SortBy.java b/core/src/main/java/org/elasticsearch/search/suggest/SortBy.java
index 14d46d134d..bab2b1ce61 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/SortBy.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/SortBy.java
@@ -36,15 +36,12 @@ public enum SortBy implements Writeable<SortBy> {
/** Sort should first be based on document frequency, then score and then the term itself. */
FREQUENCY;
- public 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 {
+ public static SortBy readFromStream(final StreamInput in) throws IOException {
int ordinal = in.readVInt();
if (ordinal < 0 || ordinal >= values().length) {
throw new IOException("Unknown SortBy ordinal [" + ordinal + "]");
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/Suggester.java b/core/src/main/java/org/elasticsearch/search/suggest/Suggester.java
index 5772f2b55d..711e3d9db7 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/Suggester.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/Suggester.java
@@ -21,18 +21,20 @@ package org.elasticsearch.search.suggest;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.util.CharsRefBuilder;
+import org.elasticsearch.common.io.stream.Writeable;
+import org.elasticsearch.index.query.QueryParseContext;
import java.io.IOException;
-public abstract class Suggester<T extends SuggestionSearchContext.SuggestionContext> {
+public abstract class Suggester<T extends SuggestionSearchContext.SuggestionContext> implements Writeable.Reader<SuggestionBuilder<?>> {
protected abstract Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>>
innerExecute(String name, T suggestion, IndexSearcher searcher, CharsRefBuilder spare) throws IOException;
/**
- * link the suggester to its corresponding {@link SuggestionBuilder}
+ * Read the SuggestionBuilder paired with this Suggester XContent.
*/
- public abstract SuggestionBuilder<? extends SuggestionBuilder> getBuilderPrototype();
+ public abstract SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException;
public Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>>
execute(String name, T suggestion, IndexSearcher searcher, CharsRefBuilder spare) throws IOException {
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/Suggesters.java b/core/src/main/java/org/elasticsearch/search/suggest/Suggesters.java
index 644d9239b8..cea00eb4ad 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/Suggesters.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/Suggesters.java
@@ -18,52 +18,50 @@
*/
package org.elasticsearch.search.suggest;
-import org.elasticsearch.common.inject.Inject;
-import org.elasticsearch.common.util.ExtensionPoint;
+import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.search.suggest.completion.CompletionSuggester;
+import org.elasticsearch.search.suggest.phrase.Laplace;
+import org.elasticsearch.search.suggest.phrase.LinearInterpolation;
import org.elasticsearch.search.suggest.phrase.PhraseSuggester;
+import org.elasticsearch.search.suggest.phrase.SmoothingModel;
+import org.elasticsearch.search.suggest.phrase.StupidBackoff;
import org.elasticsearch.search.suggest.term.TermSuggester;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
/**
*
*/
-public final class Suggesters extends ExtensionPoint.ClassMap<Suggester> {
- private final Map<String, Suggester> parsers;
+public final class Suggesters {
+ private final Map<String, Suggester<?>> suggesters = new HashMap<>();
+ private final NamedWriteableRegistry namedWriteableRegistry;
- public Suggesters() {
- this(Collections.emptyMap());
- }
+ public Suggesters(NamedWriteableRegistry namedWriteableRegistry) {
+ this.namedWriteableRegistry = namedWriteableRegistry;
+ register("phrase", PhraseSuggester.INSTANCE);
+ register("term", TermSuggester.INSTANCE);
+ register("completion", CompletionSuggester.INSTANCE);
- @Inject
- public Suggesters(Map<String, Suggester> suggesters) {
- super("suggester", Suggester.class, new HashSet<>(Arrays.asList("phrase", "term", "completion")), Suggesters.class, SuggestPhase.class);
- this.parsers = Collections.unmodifiableMap(addBuildIns(suggesters));
+ // Builtin smoothing models
+ namedWriteableRegistry.register(SmoothingModel.class, Laplace.NAME, Laplace::new);
+ namedWriteableRegistry.register(SmoothingModel.class, LinearInterpolation.NAME, LinearInterpolation::new);
+ namedWriteableRegistry.register(SmoothingModel.class, StupidBackoff.NAME, StupidBackoff::new);
}
- private static Map<String, Suggester> addBuildIns(Map<String, Suggester> suggesters) {
- final Map<String, Suggester> map = new HashMap<>();
- map.put("phrase", PhraseSuggester.PROTOTYPE);
- map.put("term", TermSuggester.PROTOTYPE);
- map.put("completion", CompletionSuggester.PROTOTYPE);
- map.putAll(suggesters);
- return map;
+ public void register(String key, Suggester<?> suggester) {
+ if (suggesters.containsKey(key)) {
+ throw new IllegalArgumentException("Can't register the same [suggester] more than once for [" + key + "]");
+ }
+ suggesters.put(key, suggester);
+ namedWriteableRegistry.register(SuggestionBuilder.class, key, suggester);
}
- public SuggestionBuilder<? extends SuggestionBuilder> getSuggestionPrototype(String suggesterName) {
- Suggester<?> suggester = parsers.get(suggesterName);
+ public Suggester<?> getSuggester(String suggesterName) {
+ Suggester<?> suggester = suggesters.get(suggesterName);
if (suggester == null) {
throw new IllegalArgumentException("suggester with name [" + suggesterName + "] not supported");
}
- SuggestionBuilder<?> suggestParser = suggester.getBuilderPrototype();
- if (suggestParser == null) {
- throw new IllegalArgumentException("suggester with name [" + suggesterName + "] not supported");
- }
- return suggestParser;
+ return suggester;
}
}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java
index 29f50649cb..aaf6d5ae6d 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java
@@ -87,6 +87,34 @@ public abstract class SuggestionBuilder<T extends SuggestionBuilder<T>> extends
}
/**
+ * Read from a stream.
+ */
+ protected SuggestionBuilder(StreamInput in) throws IOException {
+ field = in.readString();
+ text = in.readOptionalString();
+ prefix = in.readOptionalString();
+ regex = in.readOptionalString();
+ analyzer = in.readOptionalString();
+ size = in.readOptionalVInt();
+ shardSize = in.readOptionalVInt();
+ }
+
+ @Override
+ public final void writeTo(StreamOutput out) throws IOException {
+ out.writeString(field);
+ out.writeOptionalString(text);
+ out.writeOptionalString(prefix);
+ out.writeOptionalString(regex);
+ out.writeOptionalString(analyzer);
+ out.writeOptionalVInt(size);
+ out.writeOptionalVInt(shardSize);
+ doWriteTo(out);
+ }
+
+ protected abstract void doWriteTo(StreamOutput out) throws IOException;
+
+
+ /**
* Same as in {@link SuggestBuilder#setGlobalText(String)}, but in the suggestion scope.
*/
@SuppressWarnings("unchecked")
@@ -251,11 +279,7 @@ public abstract class SuggestionBuilder<T extends SuggestionBuilder<T>> extends
throw new ParsingException(parser.getTokenLocation(), "suggestion does not support [" + currentFieldName + "]");
}
} else if (token == XContentParser.Token.START_OBJECT) {
- SuggestionBuilder<?> suggestParser = suggesters.getSuggestionPrototype(currentFieldName);
- if (suggestParser == null) {
- throw new ParsingException(parser.getTokenLocation(), "suggestion [" + currentFieldName + "] not supported");
- }
- suggestionBuilder = suggestParser.innerFromXContent(parseContext);
+ suggestionBuilder = suggesters.getSuggester(currentFieldName).innerFromXContent(parseContext);
}
}
if (suggestionBuilder == null) {
@@ -273,8 +297,6 @@ public abstract class SuggestionBuilder<T extends SuggestionBuilder<T>> extends
return suggestionBuilder;
}
- protected abstract SuggestionBuilder<T> innerFromXContent(QueryParseContext parseContext) throws IOException;
-
protected abstract SuggestionContext build(QueryShardContext context) throws IOException;
/**
@@ -341,40 +363,6 @@ public abstract class SuggestionBuilder<T extends SuggestionBuilder<T>> extends
}
@Override
- public final T readFrom(StreamInput in) throws IOException {
- String field = in.readString();
- T suggestionBuilder = doReadFrom(in, field);
- suggestionBuilder.text = in.readOptionalString();
- suggestionBuilder.prefix = in.readOptionalString();
- suggestionBuilder.regex = in.readOptionalString();
- suggestionBuilder.analyzer = in.readOptionalString();
- suggestionBuilder.size = in.readOptionalVInt();
- suggestionBuilder.shardSize = in.readOptionalVInt();
- return suggestionBuilder;
- }
-
- /**
- * Subclass should return a new instance, reading itself from the input string
- * @param in the input string to read from
- * @param field the field needed for ctor or concrete suggestion
- */
- protected abstract T doReadFrom(StreamInput in, String field) throws IOException;
-
- @Override
- public final void writeTo(StreamOutput out) throws IOException {
- out.writeString(field);
- doWriteTo(out);
- out.writeOptionalString(text);
- out.writeOptionalString(prefix);
- out.writeOptionalString(regex);
- out.writeOptionalString(analyzer);
- out.writeOptionalVInt(size);
- out.writeOptionalVInt(shardSize);
- }
-
- protected abstract void doWriteTo(StreamOutput out) throws IOException;
-
- @Override
public final boolean equals(Object obj) {
if (this == obj) {
return true;
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java
index cef0a33fdd..8bf35a34b2 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java
@@ -30,12 +30,14 @@ import org.apache.lucene.search.suggest.document.TopSuggestDocs;
import org.apache.lucene.search.suggest.document.TopSuggestDocsCollector;
import org.apache.lucene.util.CharsRefBuilder;
import org.apache.lucene.util.PriorityQueue;
+import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.fielddata.AtomicFieldData;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.MapperService;
import org.elasticsearch.index.mapper.core.CompletionFieldMapper;
+import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.Suggester;
@@ -52,7 +54,9 @@ import java.util.Set;
public class CompletionSuggester extends Suggester<CompletionSuggestionContext> {
- public static final CompletionSuggester PROTOTYPE = new CompletionSuggester();
+ public static final CompletionSuggester INSTANCE = new CompletionSuggester();
+
+ private CompletionSuggester() {}
@Override
protected Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> innerExecute(String name,
@@ -267,7 +271,12 @@ public class CompletionSuggester extends Suggester<CompletionSuggestionContext>
}
@Override
- public SuggestionBuilder<?> getBuilderPrototype() {
- return CompletionSuggestionBuilder.PROTOTYPE;
+ public SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException {
+ return CompletionSuggestionBuilder.innerFromXContent(context);
+ }
+
+ @Override
+ public SuggestionBuilder<?> read(StreamInput in) throws IOException {
+ return new CompletionSuggestionBuilder(in);
}
}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java
index ca8aad7c8a..a4d2b59844 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java
@@ -40,7 +40,6 @@ import org.elasticsearch.search.suggest.SuggestionBuilder;
import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext;
import org.elasticsearch.search.suggest.completion.context.ContextMapping;
import org.elasticsearch.search.suggest.completion.context.ContextMappings;
-import org.elasticsearch.search.suggest.completion.context.QueryContext;
import java.io.IOException;
import java.util.ArrayList;
@@ -57,8 +56,6 @@ import java.util.Objects;
* indexing.
*/
public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSuggestionBuilder> {
-
- public static final CompletionSuggestionBuilder PROTOTYPE = new CompletionSuggestionBuilder("_na_");
static final String SUGGESTION_NAME = "completion";
static final ParseField PAYLOAD_FIELD = new ParseField("payload");
static final ParseField CONTEXTS_FIELD = new ParseField("contexts", "context");
@@ -125,6 +122,26 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
}
/**
+ * Read from a stream.
+ */
+ public CompletionSuggestionBuilder(StreamInput in) throws IOException {
+ super(in);
+ payloadFields = new ArrayList<>();
+ Collections.addAll(payloadFields, in.readStringArray());
+ fuzzyOptions = in.readOptionalWriteable(FuzzyOptions::new);
+ regexOptions = in.readOptionalWriteable(RegexOptions::new);
+ contextBytes = in.readOptionalBytesReference();
+ }
+
+ @Override
+ public void doWriteTo(StreamOutput out) throws IOException {
+ out.writeStringArray(payloadFields.toArray(new String[payloadFields.size()]));
+ out.writeOptionalWriteable(fuzzyOptions);
+ out.writeOptionalWriteable(regexOptions);
+ out.writeOptionalBytesReference(contextBytes);
+ }
+
+ /**
* Sets the prefix to provide completions for.
* The prefix gets analyzed by the suggest analyzer.
*/
@@ -188,12 +205,12 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
* see {@link org.elasticsearch.search.suggest.completion.context.CategoryQueryContext}
* and {@link org.elasticsearch.search.suggest.completion.context.GeoQueryContext}
*/
- public CompletionSuggestionBuilder contexts(Map<String, List<? extends QueryContext>> queryContexts) {
+ public CompletionSuggestionBuilder contexts(Map<String, List<? extends ToXContent>> queryContexts) {
Objects.requireNonNull(queryContexts, "contexts must not be null");
try {
XContentBuilder contentBuilder = XContentFactory.jsonBuilder();
contentBuilder.startObject();
- for (Map.Entry<String, List<? extends QueryContext>> contextEntry : queryContexts.entrySet()) {
+ for (Map.Entry<String, List<? extends ToXContent>> contextEntry : queryContexts.entrySet()) {
contentBuilder.startArray(contextEntry.getKey());
for (ToXContent queryContext : contextEntry.getValue()) {
queryContext.toXContent(contentBuilder, EMPTY_PARAMS);
@@ -244,8 +261,7 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
return builder;
}
- @Override
- protected CompletionSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException {
+ static CompletionSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException {
CompletionSuggestionBuilder.InnerBuilder builder = new CompletionSuggestionBuilder.InnerBuilder();
TLP_PARSER.parse(parseContext.parser(), builder);
String field = builder.field;
@@ -304,52 +320,6 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug
}
@Override
- public void doWriteTo(StreamOutput out) throws IOException {
- out.writeBoolean(payloadFields.isEmpty() == false);
- if (payloadFields.isEmpty() == false) {
- out.writeVInt(payloadFields.size());
- for (String payloadField : payloadFields) {
- out.writeString(payloadField);
- }
- }
- out.writeBoolean(fuzzyOptions != null);
- if (fuzzyOptions != null) {
- fuzzyOptions.writeTo(out);
- }
- out.writeBoolean(regexOptions != null);
- if (regexOptions != null) {
- regexOptions.writeTo(out);
- }
- out.writeBoolean(contextBytes != null);
- if (contextBytes != null) {
- out.writeBytesReference(contextBytes);
- }
- }
-
- @Override
- public CompletionSuggestionBuilder doReadFrom(StreamInput in, String field) throws IOException {
- CompletionSuggestionBuilder completionSuggestionBuilder = new CompletionSuggestionBuilder(field);
- if (in.readBoolean()) {
- int numPayloadField = in.readVInt();
- List<String> payloadFields = new ArrayList<>(numPayloadField);
- for (int i = 0; i < numPayloadField; i++) {
- payloadFields.add(in.readString());
- }
- completionSuggestionBuilder.payloadFields = payloadFields;
- }
- if (in.readBoolean()) {
- completionSuggestionBuilder.fuzzyOptions = FuzzyOptions.readFuzzyOptions(in);
- }
- if (in.readBoolean()) {
- completionSuggestionBuilder.regexOptions = RegexOptions.readRegexOptions(in);
- }
- if (in.readBoolean()) {
- completionSuggestionBuilder.contextBytes = in.readBytesReference();
- }
- return completionSuggestionBuilder;
- }
-
- @Override
protected boolean doEquals(CompletionSuggestionBuilder other) {
return Objects.equals(payloadFields, other.payloadFields) &&
Objects.equals(fuzzyOptions, other.fuzzyOptions) &&
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java
index f9f948a551..1941bc9fb8 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionContext.java
@@ -36,7 +36,7 @@ import java.util.Map;
public class CompletionSuggestionContext extends SuggestionSearchContext.SuggestionContext {
protected CompletionSuggestionContext(QueryShardContext shardContext) {
- super(CompletionSuggester.PROTOTYPE, shardContext);
+ super(CompletionSuggester.INSTANCE, shardContext);
}
private CompletionFieldMapper.CompletionFieldType fieldType;
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java
index 8f05be0469..ed2efdf456 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java
@@ -89,7 +89,26 @@ public class FuzzyOptions implements ToXContent, Writeable<FuzzyOptions> {
this.maxDeterminizedStates = maxDeterminizedStates;
}
- private FuzzyOptions() {
+ /**
+ * Read from a stream.
+ */
+ FuzzyOptions(StreamInput in) throws IOException {
+ transpositions = in.readBoolean();
+ unicodeAware = in.readBoolean();
+ editDistance = in.readVInt();
+ fuzzyMinLength = in.readVInt();
+ fuzzyPrefixLength = in.readVInt();
+ maxDeterminizedStates = in.readVInt();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeBoolean(transpositions);
+ out.writeBoolean(unicodeAware);
+ out.writeVInt(editDistance);
+ out.writeVInt(fuzzyMinLength);
+ out.writeVInt(fuzzyPrefixLength);
+ out.writeVInt(maxDeterminizedStates);
}
static FuzzyOptions parse(XContentParser parser) throws IOException {
@@ -185,33 +204,6 @@ public class FuzzyOptions implements ToXContent, Writeable<FuzzyOptions> {
return builder;
}
- public static FuzzyOptions readFuzzyOptions(StreamInput in) throws IOException {
- FuzzyOptions fuzzyOptions = new FuzzyOptions();
- fuzzyOptions.readFrom(in);
- return fuzzyOptions;
- }
-
- @Override
- public FuzzyOptions readFrom(StreamInput in) throws IOException {
- this.transpositions = in.readBoolean();
- this.unicodeAware = in.readBoolean();
- this.editDistance = in.readVInt();
- this.fuzzyMinLength = in.readVInt();
- this.fuzzyPrefixLength = in.readVInt();
- this.maxDeterminizedStates = in.readVInt();
- return this;
- }
-
- @Override
- public void writeTo(StreamOutput out) throws IOException {
- out.writeBoolean(transpositions);
- out.writeBoolean(unicodeAware);
- out.writeVInt(editDistance);
- out.writeVInt(fuzzyMinLength);
- out.writeVInt(fuzzyPrefixLength);
- out.writeVInt(maxDeterminizedStates);
- }
-
/**
* Options for fuzzy queries
*/
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java
index 8503dbdf46..58464cddee 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java
@@ -67,15 +67,26 @@ public class RegexOptions implements ToXContent, Writeable<RegexOptions> {
private int flagsValue;
private int maxDeterminizedStates;
- private RegexOptions() {
- }
-
private RegexOptions(int flagsValue, int maxDeterminizedStates) {
this.flagsValue = flagsValue;
this.maxDeterminizedStates = maxDeterminizedStates;
}
/**
+ * Read from a stream.
+ */
+ RegexOptions(StreamInput in) throws IOException {
+ this.flagsValue = in.readVInt();
+ this.maxDeterminizedStates = in.readVInt();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeVInt(flagsValue);
+ out.writeVInt(maxDeterminizedStates);
+ }
+
+ /**
* Returns internal regular expression syntax flag value
* see {@link RegexpFlag#value()}
*/
@@ -126,25 +137,6 @@ public class RegexOptions implements ToXContent, Writeable<RegexOptions> {
return builder;
}
- public static RegexOptions readRegexOptions(StreamInput in) throws IOException {
- RegexOptions regexOptions = new RegexOptions();
- regexOptions.readFrom(in);
- return regexOptions;
- }
-
- @Override
- public RegexOptions readFrom(StreamInput in) throws IOException {
- this.flagsValue = in.readVInt();
- this.maxDeterminizedStates = in.readVInt();
- return this;
- }
-
- @Override
- public void writeTo(StreamOutput out) throws IOException {
- out.writeVInt(flagsValue);
- out.writeVInt(maxDeterminizedStates);
- }
-
/**
* Options for regular expression queries
*/
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryContextMapping.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryContextMapping.java
index c9cb165aef..1931c4a9e0 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryContextMapping.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryContextMapping.java
@@ -139,8 +139,8 @@ public class CategoryContextMapping extends ContextMapping<CategoryQueryContext>
}
@Override
- protected CategoryQueryContext prototype() {
- return CategoryQueryContext.PROTOTYPE;
+ protected CategoryQueryContext fromXContent(XContentParser parser) throws IOException {
+ return CategoryQueryContext.fromXContent(parser);
}
/**
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java
index a164faff8b..2e47795010 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/CategoryQueryContext.java
@@ -22,6 +22,7 @@ package org.elasticsearch.search.suggest.completion.context;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.xcontent.ObjectParser;
+import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@@ -35,7 +36,7 @@ import static org.elasticsearch.search.suggest.completion.context.CategoryContex
/**
* Defines the query context for {@link CategoryContextMapping}
*/
-public final class CategoryQueryContext implements QueryContext {
+public final class CategoryQueryContext implements ToXContent {
public static final String NAME = "category";
public static final CategoryQueryContext PROTOTYPE = new CategoryQueryContext("", 1, false);
@@ -102,8 +103,7 @@ public final class CategoryQueryContext implements QueryContext {
CATEGORY_PARSER.declareBoolean(Builder::setPrefix, new ParseField(CONTEXT_PREFIX));
}
- @Override
- public CategoryQueryContext fromXContext(XContentParser parser) throws IOException {
+ public static CategoryQueryContext fromXContent(XContentParser parser) throws IOException {
XContentParser.Token token = parser.currentToken();
Builder builder = builder();
if (token == XContentParser.Token.START_OBJECT) {
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/ContextMapping.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/ContextMapping.java
index 959a749a85..cb445b1770 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/ContextMapping.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/ContextMapping.java
@@ -40,7 +40,7 @@ import java.util.Set;
*
* Implementations have to define how contexts are parsed at query/index time
*/
-public abstract class ContextMapping<T extends QueryContext> implements ToXContent {
+public abstract class ContextMapping<T extends ToXContent> implements ToXContent {
public static final String FIELD_TYPE = "type";
public static final String FIELD_NAME = "name";
@@ -99,7 +99,7 @@ public abstract class ContextMapping<T extends QueryContext> implements ToXConte
/**
* Prototype for the query context
*/
- protected abstract T prototype();
+ protected abstract T fromXContent(XContentParser parser) throws IOException;
/**
* Parses query contexts for this mapper
@@ -108,10 +108,10 @@ public abstract class ContextMapping<T extends QueryContext> implements ToXConte
List<T> queryContexts = new ArrayList<>();
Token token = parser.nextToken();
if (token == Token.START_OBJECT || token == Token.VALUE_STRING) {
- queryContexts.add((T) prototype().fromXContext(parser));
+ queryContexts.add(fromXContent(parser));
} else if (token == Token.START_ARRAY) {
while (parser.nextToken() != Token.END_ARRAY) {
- queryContexts.add((T) prototype().fromXContext(parser));
+ queryContexts.add(fromXContent(parser));
}
}
return toInternalQueryContexts(queryContexts);
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java
index 41d78e7535..393f798c85 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java
@@ -223,8 +223,8 @@ public class GeoContextMapping extends ContextMapping<GeoQueryContext> {
}
@Override
- protected GeoQueryContext prototype() {
- return GeoQueryContext.PROTOTYPE;
+ protected GeoQueryContext fromXContent(XContentParser parser) throws IOException {
+ return GeoQueryContext.fromXContent(parser);
}
/**
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java
index 913702c18d..43873724c0 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoQueryContext.java
@@ -24,6 +24,7 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.xcontent.ObjectParser;
+import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@@ -40,7 +41,7 @@ import static org.elasticsearch.search.suggest.completion.context.GeoContextMapp
/**
* Defines the query context for {@link GeoContextMapping}
*/
-public final class GeoQueryContext implements QueryContext {
+public final class GeoQueryContext implements ToXContent {
public static final String NAME = "geo";
public static final GeoQueryContext PROTOTYPE = new GeoQueryContext(null, 1, 12, Collections.emptyList());
@@ -123,8 +124,7 @@ public final class GeoQueryContext implements QueryContext {
GEO_CONTEXT_PARSER.declareDouble(GeoQueryContext.Builder::setLon, new ParseField("lon"));
}
- @Override
- public GeoQueryContext fromXContext(XContentParser parser) throws IOException {
+ public static GeoQueryContext fromXContent(XContentParser parser) throws IOException {
XContentParser.Token token = parser.currentToken();
GeoQueryContext.Builder builder = new Builder();
if (token == XContentParser.Token.START_OBJECT) {
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/QueryContext.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/context/QueryContext.java
deleted file mode 100644
index 9d96bf8144..0000000000
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/context/QueryContext.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.completion.context;
-
-import org.elasticsearch.common.xcontent.ToXContent;
-import org.elasticsearch.common.xcontent.XContentParser;
-
-import java.io.IOException;
-
-/**
- * Interface for serializing/de-serializing completion query context
- */
-public interface QueryContext extends ToXContent {
-
- QueryContext fromXContext(XContentParser parser) throws IOException;
-}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGenerator.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGenerator.java
index a454735ae1..58dbff64e8 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGenerator.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGenerator.java
@@ -40,8 +40,11 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-//TODO public for tests
-public final class DirectCandidateGenerator extends CandidateGenerator {
+import static java.lang.Math.log10;
+import static java.lang.Math.max;
+import static java.lang.Math.round;
+
+final class DirectCandidateGenerator extends CandidateGenerator {
private final DirectSpellChecker spellchecker;
private final String field;
@@ -59,12 +62,13 @@ public final class DirectCandidateGenerator extends CandidateGenerator {
private final BytesRefBuilder byteSpare = new BytesRefBuilder();
private final int numCandidates;
- public DirectCandidateGenerator(DirectSpellChecker spellchecker, String field, SuggestMode suggestMode, IndexReader reader, double nonErrorLikelihood, int numCandidates) throws IOException {
- this(spellchecker, field, suggestMode, reader, nonErrorLikelihood, numCandidates, null, null, MultiFields.getTerms(reader, field));
+ public DirectCandidateGenerator(DirectSpellChecker spellchecker, String field, SuggestMode suggestMode, IndexReader reader,
+ double nonErrorLikelihood, int numCandidates) throws IOException {
+ this(spellchecker, field, suggestMode, reader, nonErrorLikelihood, numCandidates, null, null, MultiFields.getTerms(reader, field));
}
-
- public DirectCandidateGenerator(DirectSpellChecker spellchecker, String field, SuggestMode suggestMode, IndexReader reader, double nonErrorLikelihood, int numCandidates, Analyzer preFilter, Analyzer postFilter, Terms terms) throws IOException {
+ public DirectCandidateGenerator(DirectSpellChecker spellchecker, String field, SuggestMode suggestMode, IndexReader reader,
+ double nonErrorLikelihood, int numCandidates, Analyzer preFilter, Analyzer postFilter, Terms terms) throws IOException {
if (terms == null) {
throw new IllegalArgumentException("generator field [" + field + "] doesn't exist");
}
@@ -113,9 +117,6 @@ public final class DirectCandidateGenerator extends CandidateGenerator {
return field;
}
- /* (non-Javadoc)
- * @see org.elasticsearch.search.suggest.phrase.CandidateGenerator#drawCandidates(org.elasticsearch.search.suggest.phrase.DirectCandidateGenerator.CandidateSet, int)
- */
@Override
public CandidateSet drawCandidates(CandidateSet set) throws IOException {
Candidate original = set.originalTerm;
@@ -127,7 +128,8 @@ public final class DirectCandidateGenerator extends CandidateGenerator {
for (int i = 0; i < suggestSimilar.length; i++) {
SuggestWord suggestWord = suggestSimilar[i];
BytesRef candidate = new BytesRef(suggestWord.string);
- postFilter(new Candidate(candidate, internalFrequency(candidate), suggestWord.score, score(suggestWord.freq, suggestWord.score, dictSize), false), spare, byteSpare, candidates);
+ postFilter(new Candidate(candidate, internalFrequency(candidate), suggestWord.score,
+ score(suggestWord.freq, suggestWord.score, dictSize), false), spare, byteSpare, candidates);
}
set.addCandidates(candidates);
return set;
@@ -148,7 +150,8 @@ public final class DirectCandidateGenerator extends CandidateGenerator {
return result.get();
}
- protected void postFilter(final Candidate candidate, final CharsRefBuilder spare, BytesRefBuilder byteSpare, final List<Candidate> candidates) throws IOException {
+ protected void postFilter(final Candidate candidate, final CharsRefBuilder spare, BytesRefBuilder byteSpare,
+ final List<Candidate> candidates) throws IOException {
if (postFilter == null) {
candidates.add(candidate);
} else {
@@ -163,9 +166,11 @@ public final class DirectCandidateGenerator extends CandidateGenerator {
// We should not use frequency(term) here because it will analyze the term again
// If preFilter and postFilter are the same analyzer it would fail.
long freq = internalFrequency(term);
- candidates.add(new Candidate(result.toBytesRef(), freq, candidate.stringDistance, score(candidate.frequency, candidate.stringDistance, dictSize), false));
+ candidates.add(new Candidate(result.toBytesRef(), freq, candidate.stringDistance,
+ score(candidate.frequency, candidate.stringDistance, dictSize), false));
} else {
- candidates.add(new Candidate(result.toBytesRef(), candidate.frequency, nonErrorLikelihood, score(candidate.frequency, candidate.stringDistance, dictSize), false));
+ candidates.add(new Candidate(result.toBytesRef(), candidate.frequency, nonErrorLikelihood,
+ score(candidate.frequency, candidate.stringDistance, dictSize), false));
}
}
}, spare);
@@ -178,7 +183,7 @@ public final class DirectCandidateGenerator extends CandidateGenerator {
protected long thresholdFrequency(long termFrequency, long dictionarySize) {
if (termFrequency > 0) {
- return Math.max(0, Math.round(termFrequency * (Math.log10(termFrequency - frequencyPlateau) * (1.0 / Math.log10(logBase))) + 1));
+ return max(0, round(termFrequency * (log10(termFrequency - frequencyPlateau) * (1.0 / log10(logBase))) + 1));
}
return 0;
@@ -232,8 +237,11 @@ public final class DirectCandidateGenerator extends CandidateGenerator {
@Override
public String toString() {
- return "Candidate [term=" + term.utf8ToString() + ", stringDistance=" + stringDistance + ", score=" + score + ", frequency=" + frequency +
- (userInput ? ", userInput" : "" ) + "]";
+ return "Candidate [term=" + term.utf8ToString()
+ + ", stringDistance=" + stringDistance
+ + ", score=" + score
+ + ", frequency=" + frequency
+ + (userInput ? ", userInput" : "") + "]";
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java
index f6a94314f5..d2fee7ccb3 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java
@@ -44,7 +44,6 @@ public final class DirectCandidateGeneratorBuilder
implements CandidateGenerator {
private static final String TYPE = "direct_generator";
- static final DirectCandidateGeneratorBuilder PROTOTYPE = new DirectCandidateGeneratorBuilder("_na_");
static final ParseField DIRECT_GENERATOR_FIELD = new ParseField(TYPE);
static final ParseField FIELDNAME_FIELD = new ParseField("field");
@@ -109,6 +108,44 @@ public final class DirectCandidateGeneratorBuilder
}
/**
+ * Read from a stream.
+ */
+ public DirectCandidateGeneratorBuilder(StreamInput in) throws IOException {
+ field = in.readString();
+ suggestMode = in.readOptionalString();
+ accuracy = in.readOptionalFloat();
+ size = in.readOptionalVInt();
+ sort = in.readOptionalString();
+ stringDistance = in.readOptionalString();
+ maxEdits = in.readOptionalVInt();
+ maxInspections = in.readOptionalVInt();
+ maxTermFreq = in.readOptionalFloat();
+ prefixLength = in.readOptionalVInt();
+ minWordLength = in.readOptionalVInt();
+ minDocFreq = in.readOptionalFloat();
+ preFilter = in.readOptionalString();
+ postFilter = in.readOptionalString();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeString(field);
+ out.writeOptionalString(suggestMode);
+ out.writeOptionalFloat(accuracy);
+ out.writeOptionalVInt(size);
+ out.writeOptionalString(sort);
+ out.writeOptionalString(stringDistance);
+ out.writeOptionalVInt(maxEdits);
+ out.writeOptionalVInt(maxInspections);
+ out.writeOptionalFloat(maxTermFreq);
+ out.writeOptionalVInt(prefixLength);
+ out.writeOptionalVInt(minWordLength);
+ out.writeOptionalFloat(minDocFreq);
+ out.writeOptionalString(preFilter);
+ out.writeOptionalString(postFilter);
+ }
+
+ /**
* The global suggest mode controls what suggested terms are included or
* controls for what suggest text tokens, terms should be suggested for.
* Three possible values can be specified:
@@ -334,15 +371,11 @@ public final class DirectCandidateGeneratorBuilder
PARSER.declareInt((tp, i) -> tp.v2().prefixLength(i), PREFIX_LENGTH_FIELD);
}
- @Override
- public DirectCandidateGeneratorBuilder fromXContent(QueryParseContext parseContext) throws IOException {
+ public static DirectCandidateGeneratorBuilder fromXContent(QueryParseContext parseContext) throws IOException {
DirectCandidateGeneratorBuilder tempGenerator = new DirectCandidateGeneratorBuilder("_na_");
- Set<String> tmpFieldName = new HashSet<>(1); // bucket for the field
- // name, needed as
- // constructor arg
- // later
- PARSER.parse(parseContext.parser(),
- new Tuple<Set<String>, DirectCandidateGeneratorBuilder>(tmpFieldName, tempGenerator));
+ // bucket for the field name, needed as constructor arg later
+ Set<String> tmpFieldName = new HashSet<>(1);
+ PARSER.parse(parseContext.parser(), new Tuple<Set<String>, DirectCandidateGeneratorBuilder>(tmpFieldName, tempGenerator));
if (tmpFieldName.size() != 1) {
throw new IllegalArgumentException("[" + TYPE + "] expects exactly one field parameter, but found " + tmpFieldName);
}
@@ -406,58 +439,6 @@ public final class DirectCandidateGeneratorBuilder
}
@Override
- public DirectCandidateGeneratorBuilder readFrom(StreamInput in) throws IOException {
- DirectCandidateGeneratorBuilder cg = new DirectCandidateGeneratorBuilder(in.readString());
- cg.suggestMode = in.readOptionalString();
- if (in.readBoolean()) {
- cg.accuracy = in.readFloat();
- }
- cg.size = in.readOptionalVInt();
- cg.sort = in.readOptionalString();
- cg.stringDistance = in.readOptionalString();
- cg.maxEdits = in.readOptionalVInt();
- cg.maxInspections = in.readOptionalVInt();
- if (in.readBoolean()) {
- cg.maxTermFreq = in.readFloat();
- }
- cg.prefixLength = in.readOptionalVInt();
- cg.minWordLength = in.readOptionalVInt();
- if (in.readBoolean()) {
- cg.minDocFreq = in.readFloat();
- }
- cg.preFilter = in.readOptionalString();
- cg.postFilter = in.readOptionalString();
- return cg;
- }
-
- @Override
- public void writeTo(StreamOutput out) throws IOException {
- out.writeString(field);
- out.writeOptionalString(suggestMode);
- out.writeBoolean(accuracy != null);
- if (accuracy != null) {
- out.writeFloat(accuracy);
- }
- out.writeOptionalVInt(size);
- out.writeOptionalString(sort);
- out.writeOptionalString(stringDistance);
- out.writeOptionalVInt(maxEdits);
- out.writeOptionalVInt(maxInspections);
- out.writeBoolean(maxTermFreq != null);
- if (maxTermFreq != null) {
- out.writeFloat(maxTermFreq);
- }
- out.writeOptionalVInt(prefixLength);
- out.writeOptionalVInt(minWordLength);
- out.writeBoolean(minDocFreq != null);
- if (minDocFreq != null) {
- out.writeFloat(minDocFreq);
- }
- out.writeOptionalString(preFilter);
- out.writeOptionalString(postFilter);
- }
-
- @Override
public final int hashCode() {
return Objects.hash(field, preFilter, postFilter, suggestMode, accuracy,
size, sort, stringDistance, maxEdits, maxInspections,
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java
index e11a920f96..15eb759f2a 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java
@@ -44,15 +44,15 @@ import java.util.Objects;
* </p>
*/
public final class Laplace extends SmoothingModel {
- private double alpha = DEFAULT_LAPLACE_ALPHA;
- private static final String NAME = "laplace";
+ public static final String NAME = "laplace";
private static final ParseField ALPHA_FIELD = new ParseField("alpha");
static final ParseField PARSE_FIELD = new ParseField(NAME);
/**
* Default alpha parameter for laplace smoothing
*/
public static final double DEFAULT_LAPLACE_ALPHA = 0.5;
- public static final Laplace PROTOTYPE = new Laplace(DEFAULT_LAPLACE_ALPHA);
+
+ private double alpha = DEFAULT_LAPLACE_ALPHA;
/**
* Creates a Laplace smoothing model.
@@ -63,6 +63,18 @@ public final class Laplace extends SmoothingModel {
}
/**
+ * Read from a stream.
+ */
+ public Laplace(StreamInput in) throws IOException {
+ alpha = in.readDouble();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeDouble(alpha);
+ }
+
+ /**
* @return the laplace model alpha parameter
*/
public double getAlpha() {
@@ -81,16 +93,6 @@ public final class Laplace extends SmoothingModel {
}
@Override
- public void writeTo(StreamOutput out) throws IOException {
- out.writeDouble(alpha);
- }
-
- @Override
- public SmoothingModel readFrom(StreamInput in) throws IOException {
- return new Laplace(in.readDouble());
- }
-
- @Override
protected boolean doEquals(SmoothingModel other) {
Laplace otherModel = (Laplace) other;
return Objects.equals(alpha, otherModel.alpha);
@@ -101,8 +103,7 @@ public final class Laplace extends SmoothingModel {
return Objects.hash(alpha);
}
- @Override
- public SmoothingModel innerFromXContent(QueryParseContext parseContext) throws IOException {
+ public static SmoothingModel innerFromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token;
String fieldName = null;
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/LaplaceScorer.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/LaplaceScorer.java
index 678f3082ba..6b6301b49a 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/LaplaceScorer.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/LaplaceScorer.java
@@ -25,19 +25,11 @@ import org.elasticsearch.search.suggest.SuggestUtils;
import org.elasticsearch.search.suggest.phrase.DirectCandidateGenerator.Candidate;
import java.io.IOException;
-//TODO public for tests
-public final class LaplaceScorer extends WordScorer {
-
- public static final WordScorerFactory FACTORY = new WordScorer.WordScorerFactory() {
- @Override
- public WordScorer newScorer(IndexReader reader, Terms terms, String field, double realWordLikelyhood, BytesRef separator) throws IOException {
- return new LaplaceScorer(reader, terms, field, realWordLikelyhood, separator, 0.5);
- }
- };
+final class LaplaceScorer extends WordScorer {
private double alpha;
- public LaplaceScorer(IndexReader reader, Terms terms, String field,
+ LaplaceScorer(IndexReader reader, Terms terms, String field,
double realWordLikelyhood, BytesRef separator, double alpha) throws IOException {
super(reader, terms, field, realWordLikelyhood, separator);
this.alpha = alpha;
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpoatingScorer.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpoatingScorer.java
index 368d461fc5..f369523167 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpoatingScorer.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpoatingScorer.java
@@ -33,8 +33,8 @@ public final class LinearInterpoatingScorer extends WordScorer {
private final double bigramLambda;
private final double trigramLambda;
- public LinearInterpoatingScorer(IndexReader reader, Terms terms, String field, double realWordLikelyhood, BytesRef separator, double trigramLambda, double bigramLambda, double unigramLambda)
- throws IOException {
+ public LinearInterpoatingScorer(IndexReader reader, Terms terms, String field, double realWordLikelyhood, BytesRef separator,
+ double trigramLambda, double bigramLambda, double unigramLambda) throws IOException {
super(reader, terms, field, realWordLikelyhood, separator);
double sum = unigramLambda + bigramLambda + trigramLambda;
this.unigramLambda = unigramLambda / sum;
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java
index b94ea333fd..8021edcc78 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java
@@ -45,16 +45,16 @@ import java.util.Objects;
* </p>
*/
public final class LinearInterpolation extends SmoothingModel {
- private static final String NAME = "linear";
- public static final LinearInterpolation PROTOTYPE = new LinearInterpolation(0.8, 0.1, 0.1);
- private final double trigramLambda;
- private final double bigramLambda;
- private final double unigramLambda;
+ public static final String NAME = "linear";
static final ParseField PARSE_FIELD = new ParseField(NAME);
private static final ParseField TRIGRAM_FIELD = new ParseField("trigram_lambda");
private static final ParseField BIGRAM_FIELD = new ParseField("bigram_lambda");
private static final ParseField UNIGRAM_FIELD = new ParseField("unigram_lambda");
+ private final double trigramLambda;
+ private final double bigramLambda;
+ private final double unigramLambda;
+
/**
* Creates a linear interpolation smoothing model.
*
@@ -77,6 +77,22 @@ public final class LinearInterpolation extends SmoothingModel {
this.unigramLambda = unigramLambda;
}
+ /**
+ * Read from a stream.
+ */
+ public LinearInterpolation(StreamInput in) throws IOException {
+ trigramLambda = in.readDouble();
+ bigramLambda = in.readDouble();
+ unigramLambda = in.readDouble();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeDouble(trigramLambda);
+ out.writeDouble(bigramLambda);
+ out.writeDouble(unigramLambda);
+ }
+
public double getTrigramLambda() {
return this.trigramLambda;
}
@@ -103,18 +119,6 @@ public final class LinearInterpolation extends SmoothingModel {
}
@Override
- public void writeTo(StreamOutput out) throws IOException {
- out.writeDouble(trigramLambda);
- out.writeDouble(bigramLambda);
- out.writeDouble(unigramLambda);
- }
-
- @Override
- public LinearInterpolation readFrom(StreamInput in) throws IOException {
- return new LinearInterpolation(in.readDouble(), in.readDouble(), in.readDouble());
- }
-
- @Override
protected boolean doEquals(SmoothingModel other) {
final LinearInterpolation otherModel = (LinearInterpolation) other;
return Objects.equals(trigramLambda, otherModel.trigramLambda) &&
@@ -127,8 +131,7 @@ public final class LinearInterpolation extends SmoothingModel {
return Objects.hash(trigramLambda, bigramLambda, unigramLambda);
}
- @Override
- public LinearInterpolation innerFromXContent(QueryParseContext parseContext) throws IOException {
+ public static LinearInterpolation innerFromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token;
String fieldName = null;
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java
index 14bced639f..11a0c10ee0 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java
@@ -29,9 +29,11 @@ import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.CharsRefBuilder;
import org.elasticsearch.common.bytes.BytesReference;
+import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.ParsedQuery;
+import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.script.CompiledScript;
import org.elasticsearch.script.ExecutableScript;
import org.elasticsearch.script.ScriptService;
@@ -53,7 +55,9 @@ public final class PhraseSuggester extends Suggester<PhraseSuggestionContext> {
private final BytesRef SEPARATOR = new BytesRef(" ");
private static final String SUGGESTION_TEMPLATE_VAR_NAME = "suggestion";
- public static final PhraseSuggester PROTOTYPE = new PhraseSuggester();
+ public static final PhraseSuggester INSTANCE = new PhraseSuggester();
+
+ private PhraseSuggester() {}
/*
* More Ideas:
@@ -144,8 +148,12 @@ public final class PhraseSuggester extends Suggester<PhraseSuggestionContext> {
}
@Override
- public SuggestionBuilder<?> getBuilderPrototype() {
- return PhraseSuggestionBuilder.PROTOTYPE;
+ public SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException {
+ return PhraseSuggestionBuilder.innerFromXContent(context);
}
+ @Override
+ public SuggestionBuilder<?> read(StreamInput in) throws IOException {
+ return new PhraseSuggestionBuilder(in);
+ }
}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java
index a4793dfbda..299c57d8d2 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java
@@ -60,8 +60,6 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
private static final String SUGGESTION_NAME = "phrase";
- public static final PhraseSuggestionBuilder PROTOTYPE = new PhraseSuggestionBuilder("_na_");
-
protected static final ParseField MAXERRORS_FIELD = new ParseField("max_errors");
protected static final ParseField RWE_LIKELIHOOD_FIELD = new ParseField("real_word_error_likelihood");
protected static final ParseField SEPARATOR_FIELD = new ParseField("separator");
@@ -122,6 +120,76 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
}
/**
+ * Read from a stream.
+ */
+ PhraseSuggestionBuilder(StreamInput in) throws IOException {
+ super(in);
+ maxErrors = in.readFloat();
+ realWordErrorLikelihood = in.readFloat();
+ confidence = in.readFloat();
+ gramSize = in.readOptionalVInt();
+ if (in.readBoolean()) {
+ model = in.readPhraseSuggestionSmoothingModel();
+ }
+ forceUnigrams = in.readBoolean();
+ tokenLimit = in.readVInt();
+ preTag = in.readOptionalString();
+ postTag = in.readOptionalString();
+ separator = in.readString();
+ if (in.readBoolean()) {
+ collateQuery = Template.readTemplate(in);
+ }
+ collateParams = in.readMap();
+ collatePrune = in.readOptionalBoolean();
+ int generatorsEntries = in.readVInt();
+ for (int i = 0; i < generatorsEntries; i++) {
+ String type = in.readString();
+ int numberOfGenerators = in.readVInt();
+ List<CandidateGenerator> generatorsList = new ArrayList<>(numberOfGenerators);
+ for (int g = 0; g < numberOfGenerators; g++) {
+ DirectCandidateGeneratorBuilder generator = new DirectCandidateGeneratorBuilder(in);
+ generatorsList.add(generator);
+ }
+ generators.put(type, generatorsList);
+ }
+ }
+
+ @Override
+ public void doWriteTo(StreamOutput out) throws IOException {
+ out.writeFloat(maxErrors);
+ out.writeFloat(realWordErrorLikelihood);
+ out.writeFloat(confidence);
+ out.writeOptionalVInt(gramSize);
+ boolean hasModel = model != null;
+ out.writeBoolean(hasModel);
+ if (hasModel) {
+ out.writePhraseSuggestionSmoothingModel(model);
+ }
+ out.writeBoolean(forceUnigrams);
+ out.writeVInt(tokenLimit);
+ out.writeOptionalString(preTag);
+ out.writeOptionalString(postTag);
+ out.writeString(separator);
+ if (collateQuery != null) {
+ out.writeBoolean(true);
+ collateQuery.writeTo(out);
+ } else {
+ out.writeBoolean(false);
+ }
+ out.writeMap(collateParams);
+ out.writeOptionalBoolean(collatePrune);
+ out.writeVInt(this.generators.size());
+ for (Entry<String, List<CandidateGenerator>> entry : this.generators.entrySet()) {
+ out.writeString(entry.getKey());
+ List<CandidateGenerator> generatorsList = entry.getValue();
+ out.writeVInt(generatorsList.size());
+ for (CandidateGenerator generator : generatorsList) {
+ generator.writeTo(out);
+ }
+ }
+ }
+
+ /**
* Sets the gram size for the n-gram model used for this suggester. The
* default value is <tt>1</tt> corresponding to <tt>unigrams</tt>. Use
* <tt>2</tt> for <tt>bigrams</tt> and <tt>3</tt> for <tt>trigrams</tt>.
@@ -422,8 +490,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
return builder;
}
- @Override
- protected PhraseSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException {
+ static PhraseSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
PhraseSuggestionBuilder tmpSuggestion = new PhraseSuggestionBuilder("_na_");
ParseFieldMatcher parseFieldMatcher = parseContext.parseFieldMatcher();
@@ -464,7 +531,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
if (parseFieldMatcher.match(currentFieldName, DirectCandidateGeneratorBuilder.DIRECT_GENERATOR_FIELD)) {
// for now we only have a single type of generators
while ((token = parser.nextToken()) == Token.START_OBJECT) {
- tmpSuggestion.addCandidateGenerator(DirectCandidateGeneratorBuilder.PROTOTYPE.fromXContent(parseContext));
+ tmpSuggestion.addCandidateGenerator(DirectCandidateGeneratorBuilder.fromXContent(parseContext));
}
} else {
throw new ParsingException(parser.getTokenLocation(),
@@ -578,10 +645,6 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
suggestionContext.setCollatePrune(this.collatePrune);
}
- if (suggestionContext.model() == null) {
- suggestionContext.setModel(StupidBackoffScorer.FACTORY);
- }
-
if (this.gramSize == null || suggestionContext.generators().isEmpty()) {
final ShingleTokenFilterFactory.Factory shingleFilterFactory = SuggestUtils
.getShingleFilterFactory(suggestionContext.getAnalyzer());
@@ -624,75 +687,6 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
}
@Override
- public void doWriteTo(StreamOutput out) throws IOException {
- out.writeFloat(maxErrors);
- out.writeFloat(realWordErrorLikelihood);
- out.writeFloat(confidence);
- out.writeOptionalVInt(gramSize);
- boolean hasModel = model != null;
- out.writeBoolean(hasModel);
- if (hasModel) {
- out.writePhraseSuggestionSmoothingModel(model);
- }
- out.writeBoolean(forceUnigrams);
- out.writeVInt(tokenLimit);
- out.writeOptionalString(preTag);
- out.writeOptionalString(postTag);
- out.writeString(separator);
- if (collateQuery != null) {
- out.writeBoolean(true);
- collateQuery.writeTo(out);
- } else {
- out.writeBoolean(false);
- }
- out.writeMap(collateParams);
- out.writeOptionalBoolean(collatePrune);
- out.writeVInt(this.generators.size());
- for (Entry<String, List<CandidateGenerator>> entry : this.generators.entrySet()) {
- out.writeString(entry.getKey());
- List<CandidateGenerator> generatorsList = entry.getValue();
- out.writeVInt(generatorsList.size());
- for (CandidateGenerator generator : generatorsList) {
- generator.writeTo(out);
- }
- }
- }
-
- @Override
- public PhraseSuggestionBuilder doReadFrom(StreamInput in, String field) throws IOException {
- PhraseSuggestionBuilder builder = new PhraseSuggestionBuilder(field);
- builder.maxErrors = in.readFloat();
- builder.realWordErrorLikelihood = in.readFloat();
- builder.confidence = in.readFloat();
- builder.gramSize = in.readOptionalVInt();
- if (in.readBoolean()) {
- builder.model = in.readPhraseSuggestionSmoothingModel();
- }
- builder.forceUnigrams = in.readBoolean();
- builder.tokenLimit = in.readVInt();
- builder.preTag = in.readOptionalString();
- builder.postTag = in.readOptionalString();
- builder.separator = in.readString();
- if (in.readBoolean()) {
- builder.collateQuery = Template.readTemplate(in);
- }
- builder.collateParams = in.readMap();
- builder.collatePrune = in.readOptionalBoolean();
- int generatorsEntries = in.readVInt();
- for (int i = 0; i < generatorsEntries; i++) {
- String type = in.readString();
- int numberOfGenerators = in.readVInt();
- List<CandidateGenerator> generatorsList = new ArrayList<>(numberOfGenerators);
- for (int g = 0; g < numberOfGenerators; g++) {
- DirectCandidateGeneratorBuilder generator = DirectCandidateGeneratorBuilder.PROTOTYPE.readFrom(in);
- generatorsList.add(generator);
- }
- builder.generators.put(type, generatorsList);
- }
- return builder;
- }
-
- @Override
protected boolean doEquals(PhraseSuggestionBuilder other) {
return Objects.equals(maxErrors, other.maxErrors) &&
Objects.equals(separator, other.separator) &&
@@ -723,8 +717,6 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB
public interface CandidateGenerator extends Writeable<CandidateGenerator>, ToXContent {
String getType();
- CandidateGenerator fromXContent(QueryParseContext parseContext) throws IOException;
-
PhraseSuggestionContext.DirectCandidateGenerator build(MapperService mapperService) throws IOException;
}
}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionContext.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionContext.java
index 80ac850a38..e2d7ff1c41 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionContext.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionContext.java
@@ -19,6 +19,8 @@
package org.elasticsearch.search.suggest.phrase;
import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Terms;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.script.CompiledScript;
@@ -38,6 +40,8 @@ class PhraseSuggestionContext extends SuggestionContext {
static final float DEFAULT_RWE_ERRORLIKELIHOOD = 0.95f;
static final float DEFAULT_MAX_ERRORS = 0.5f;
static final String DEFAULT_SEPARATOR = " ";
+ static final WordScorer.WordScorerFactory DEFAULT_SCORER = (IndexReader reader, Terms terms, String field, double realWordLikelyhood,
+ BytesRef separator) -> new StupidBackoffScorer(reader, terms, field, realWordLikelyhood, separator, 0.4f);
private float maxErrors = DEFAULT_MAX_ERRORS;
private BytesRef separator = new BytesRef(DEFAULT_SEPARATOR);
@@ -52,10 +56,10 @@ class PhraseSuggestionContext extends SuggestionContext {
private boolean prune = DEFAULT_COLLATE_PRUNE;
private List<DirectCandidateGenerator> generators = new ArrayList<>();
private Map<String, Object> collateScriptParams = new HashMap<>(1);
- private WordScorer.WordScorerFactory scorer;
+ private WordScorer.WordScorerFactory scorer = DEFAULT_SCORER;
public PhraseSuggestionContext(QueryShardContext shardContext) {
- super(PhraseSuggester.PROTOTYPE, shardContext);
+ super(PhraseSuggester.INSTANCE, shardContext);
}
public float maxErrors() {
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java
index 0163c560de..d2b5b30dc5 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java
@@ -76,11 +76,11 @@ public abstract class SmoothingModel implements NamedWriteable<SmoothingModel>,
fieldName = parser.currentName();
} else if (token == XContentParser.Token.START_OBJECT) {
if (parseFieldMatcher.match(fieldName, LinearInterpolation.PARSE_FIELD)) {
- model = LinearInterpolation.PROTOTYPE.innerFromXContent(parseContext);
+ model = LinearInterpolation.innerFromXContent(parseContext);
} else if (parseFieldMatcher.match(fieldName, Laplace.PARSE_FIELD)) {
- model = Laplace.PROTOTYPE.innerFromXContent(parseContext);
+ model = Laplace.innerFromXContent(parseContext);
} else if (parseFieldMatcher.match(fieldName, StupidBackoff.PARSE_FIELD)) {
- model = StupidBackoff.PROTOTYPE.innerFromXContent(parseContext);
+ model = StupidBackoff.innerFromXContent(parseContext);
} else {
throw new IllegalArgumentException("suggester[phrase] doesn't support object field [" + fieldName + "]");
}
@@ -92,8 +92,6 @@ public abstract class SmoothingModel implements NamedWriteable<SmoothingModel>,
return model;
}
- public abstract SmoothingModel innerFromXContent(QueryParseContext parseContext) throws IOException;
-
public abstract WordScorerFactory buildWordScorerFactory();
/**
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java
index 951f7f917f..cf1c436640 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java
@@ -49,12 +49,12 @@ public final class StupidBackoff extends SmoothingModel {
* Default discount parameter for {@link StupidBackoff} smoothing
*/
public static final double DEFAULT_BACKOFF_DISCOUNT = 0.4;
- public static final StupidBackoff PROTOTYPE = new StupidBackoff(DEFAULT_BACKOFF_DISCOUNT);
- private double discount = DEFAULT_BACKOFF_DISCOUNT;
- private static final String NAME = "stupid_backoff";
+ public static final String NAME = "stupid_backoff";
private static final ParseField DISCOUNT_FIELD = new ParseField("discount");
static final ParseField PARSE_FIELD = new ParseField(NAME);
+ private double discount = DEFAULT_BACKOFF_DISCOUNT;
+
/**
* Creates a Stupid-Backoff smoothing model.
*
@@ -66,6 +66,18 @@ public final class StupidBackoff extends SmoothingModel {
}
/**
+ * Read from a stream.
+ */
+ public StupidBackoff(StreamInput in) throws IOException {
+ discount = in.readDouble();
+ }
+
+ @Override
+ public void writeTo(StreamOutput out) throws IOException {
+ out.writeDouble(discount);
+ }
+
+ /**
* @return the discount parameter of the model
*/
public double getDiscount() {
@@ -84,16 +96,6 @@ public final class StupidBackoff extends SmoothingModel {
}
@Override
- public void writeTo(StreamOutput out) throws IOException {
- out.writeDouble(discount);
- }
-
- @Override
- public StupidBackoff readFrom(StreamInput in) throws IOException {
- return new StupidBackoff(in.readDouble());
- }
-
- @Override
protected boolean doEquals(SmoothingModel other) {
StupidBackoff otherModel = (StupidBackoff) other;
return Objects.equals(discount, otherModel.discount);
@@ -104,8 +106,7 @@ public final class StupidBackoff extends SmoothingModel {
return Objects.hash(discount);
}
- @Override
- public SmoothingModel innerFromXContent(QueryParseContext parseContext) throws IOException {
+ public static SmoothingModel innerFromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
XContentParser.Token token;
String fieldName = null;
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoffScorer.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoffScorer.java
index 5bd3d942b1..ed0573bf00 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoffScorer.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoffScorer.java
@@ -26,14 +26,7 @@ import org.elasticsearch.search.suggest.phrase.DirectCandidateGenerator.Candidat
import java.io.IOException;
-public class StupidBackoffScorer extends WordScorer {
- public static final WordScorerFactory FACTORY = new WordScorer.WordScorerFactory() {
- @Override
- public WordScorer newScorer(IndexReader reader, Terms terms, String field, double realWordLikelyhood, BytesRef separator) throws IOException {
- return new StupidBackoffScorer(reader, terms, field, realWordLikelyhood, separator, 0.4f);
- }
- };
-
+class StupidBackoffScorer extends WordScorer {
private final double discount;
public StupidBackoffScorer(IndexReader reader, Terms terms,String field, double realWordLikelyhood, BytesRef separator, double discount)
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java
index 4bffb2dfe8..a06baccb99 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java
@@ -27,7 +27,9 @@ import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.CharsRefBuilder;
import org.elasticsearch.common.bytes.BytesArray;
+import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.text.Text;
+import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.search.suggest.SuggestUtils;
import org.elasticsearch.search.suggest.Suggester;
import org.elasticsearch.search.suggest.SuggestionBuilder;
@@ -39,7 +41,9 @@ import java.util.List;
public final class TermSuggester extends Suggester<TermSuggestionContext> {
- public static final TermSuggester PROTOTYPE = new TermSuggester();
+ public static final TermSuggester INSTANCE = new TermSuggester();
+
+ private TermSuggester() {}
@Override
public TermSuggestion innerExecute(String name, TermSuggestionContext suggestion, IndexSearcher searcher, CharsRefBuilder spare)
@@ -79,6 +83,16 @@ public final class TermSuggester extends Suggester<TermSuggestionContext> {
return result;
}
+ @Override
+ public SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException {
+ return TermSuggestionBuilder.innerFromXContent(context);
+ }
+
+ @Override
+ public SuggestionBuilder<?> read(StreamInput in) throws IOException {
+ return new TermSuggestionBuilder(in);
+ }
+
private static class Token {
public final Term term;
@@ -92,10 +106,4 @@ public final class TermSuggester extends Suggester<TermSuggestionContext> {
}
}
-
- @Override
- public SuggestionBuilder<?> getBuilderPrototype() {
- return TermSuggestionBuilder.PROTOTYPE;
- }
-
}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestion.java b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestion.java
index bc4006469a..dc29b6a148 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestion.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestion.java
@@ -111,7 +111,7 @@ public class TermSuggestion extends Suggestion<TermSuggestion.Entry> {
@Override
protected void innerReadFrom(StreamInput in) throws IOException {
super.innerReadFrom(in);
- sort = SortBy.PROTOTYPE.readFrom(in);
+ sort = SortBy.readFromStream(in);
}
@Override
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java
index 0cb9d1604a..0676bbf859 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java
@@ -69,8 +69,6 @@ import static org.elasticsearch.search.suggest.SuggestUtils.Fields.SUGGEST_MODE;
* global options, but are only applicable for this suggestion.
*/
public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuilder> {
-
- public static final TermSuggestionBuilder PROTOTYPE = new TermSuggestionBuilder("_na_");
private static final String SUGGESTION_NAME = "term";
private SuggestMode suggestMode = SuggestMode.MISSING;
@@ -106,6 +104,37 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
}
/**
+ * Read from a stream.
+ */
+ TermSuggestionBuilder(StreamInput in) throws IOException {
+ super(in);
+ suggestMode = SuggestMode.readFromStream(in);
+ accuracy = in.readFloat();
+ sort = SortBy.readFromStream(in);
+ stringDistance = StringDistanceImpl.readFromStream(in);
+ maxEdits = in.readVInt();
+ maxInspections = in.readVInt();
+ maxTermFreq = in.readFloat();
+ prefixLength = in.readVInt();
+ minWordLength = in.readVInt();
+ minDocFreq = in.readFloat();
+ }
+
+ @Override
+ public void doWriteTo(StreamOutput out) throws IOException {
+ 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);
+ }
+
+ /**
* The global suggest mode controls what suggested terms are included or
* controls for what suggest text tokens, terms should be suggested for.
* Three possible values can be specified:
@@ -360,8 +389,7 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
return builder;
}
- @Override
- protected TermSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException {
+ static TermSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException {
XContentParser parser = parseContext.parser();
TermSuggestionBuilder tmpSuggestion = new TermSuggestionBuilder("_na_");
ParseFieldMatcher parseFieldMatcher = parseContext.parseFieldMatcher();
@@ -443,36 +471,6 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
}
@Override
- public void doWriteTo(StreamOutput out) throws IOException {
- 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 field) throws IOException {
- TermSuggestionBuilder builder = new TermSuggestionBuilder(field);
- 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) {
return Objects.equals(suggestMode, other.suggestMode) &&
Objects.equals(accuracy, other.accuracy) &&
@@ -516,15 +514,12 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
}
};
- 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 {
+ public static SuggestMode readFromStream(final StreamInput in) throws IOException {
int ordinal = in.readVInt();
if (ordinal < 0 || ordinal >= values().length) {
throw new IOException("Unknown SuggestMode ordinal [" + ordinal + "]");
@@ -579,15 +574,12 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild
}
};
- 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 {
+ public static StringDistanceImpl readFromStream(final StreamInput in) throws IOException {
int ordinal = in.readVInt();
if (ordinal < 0 || ordinal >= values().length) {
throw new IOException("Unknown StringDistanceImpl ordinal [" + ordinal + "]");
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionContext.java b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionContext.java
index 5102ef9901..c950e5729d 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionContext.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionContext.java
@@ -27,7 +27,7 @@ final class TermSuggestionContext extends SuggestionContext {
private final DirectSpellcheckerSettings settings = new DirectSpellcheckerSettings();
public TermSuggestionContext(QueryShardContext shardContext) {
- super(TermSuggester.PROTOTYPE, shardContext);
+ super(TermSuggester.INSTANCE, shardContext);
}
public DirectSpellcheckerSettings getDirectSpellCheckerSettings() {