summaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
authorChristoph Büscher <christoph@elastic.co>2017-02-20 15:45:10 +0100
committerGitHub <noreply@github.com>2017-02-20 15:45:10 +0100
commitea7deace5dd3c293dadb508979511c28d785588d (patch)
tree38f93d28c765169014cb6e458edd4bf00d157e3d /core/src/main
parentea9d51114c6da056fb3b1bae6a6ece4d29edf922 (diff)
Adding fromXContent to Suggest and Suggestion class (#23226)
A follow up to #23202, this adds parsing from xContent and tests to the four Suggestion implementations and the top level suggest element to be used later when parsing the entire SearchResponse.
Diffstat (limited to 'core/src/main')
-rw-r--r--core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java10
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/Suggest.java67
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestion.java2
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestion.java2
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestion.java2
5 files changed, 76 insertions, 7 deletions
diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java
index 968ad8ac6b..0c6cb1c5cd 100644
--- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java
+++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java
@@ -448,12 +448,20 @@ public class XContentHelper {
* {@link XContentType}. Wraps the output into a new anonymous object.
*/
public static BytesReference toXContent(ToXContent toXContent, XContentType xContentType, boolean humanReadable) throws IOException {
+ return toXContent(toXContent, xContentType, ToXContent.EMPTY_PARAMS, humanReadable);
+ }
+
+ /**
+ * Returns the bytes that represent the XContent output of the provided {@link ToXContent} object, using the provided
+ * {@link XContentType}. Wraps the output into a new anonymous object.
+ */
+ public static BytesReference toXContent(ToXContent toXContent, XContentType xContentType, Params params, boolean humanReadable) throws IOException {
try (XContentBuilder builder = XContentBuilder.builder(xContentType.xContent())) {
builder.humanReadable(humanReadable);
if (toXContent.isFragment()) {
builder.startObject();
}
- toXContent.toXContent(builder, ToXContent.EMPTY_PARAMS);
+ toXContent.toXContent(builder, params);
if (toXContent.isFragment()) {
builder.endObject();
}
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/Suggest.java b/core/src/main/java/org/elasticsearch/search/suggest/Suggest.java
index 36a780fec3..ba5ad712f4 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/Suggest.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/Suggest.java
@@ -20,6 +20,7 @@ package org.elasticsearch.search.suggest;
import org.apache.lucene.util.CollectionUtil;
import org.elasticsearch.common.ParseField;
+import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable;
@@ -47,17 +48,19 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.function.Function;
import java.util.stream.Collectors;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.optionalConstructorArg;
+import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
/**
* Top level suggest result, containing the result for each suggestion.
*/
public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? extends Option>>>, Streamable, ToXContent {
- private static final String NAME = "suggest";
+ static final String NAME = "suggest";
public static final Comparator<Option> COMPARATOR = (first, second) -> {
int cmp = Float.compare(second.getScore(), first.getScore());
@@ -72,7 +75,7 @@ public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? ex
private Map<String, Suggestion<? extends Entry<? extends Option>>> suggestMap;
- public Suggest() {
+ private Suggest() {
this(Collections.emptyList());
}
@@ -167,6 +170,18 @@ public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? ex
return builder;
}
+ /**
+ * this parsing method assumes that the leading "suggest" field name has already been parsed by the caller
+ */
+ public static Suggest fromXContent(XContentParser parser) throws IOException {
+ ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.currentToken(), parser::getTokenLocation);
+ List<Suggestion<? extends Entry<? extends Option>>> suggestions = new ArrayList<>();
+ while ((parser.nextToken()) != XContentParser.Token.END_OBJECT) {
+ suggestions.add(Suggestion.fromXContent(parser));
+ }
+ return new Suggest(suggestions);
+ }
+
public static Suggest readSuggest(StreamInput in) throws IOException {
Suggest result = new Suggest();
result.readFrom(in);
@@ -216,7 +231,7 @@ public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? ex
protected int size;
protected final List<T> entries = new ArrayList<>(5);
- public Suggestion() {
+ protected Suggestion() {
}
public Suggestion(String name, int size) {
@@ -369,6 +384,52 @@ public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? ex
return builder;
}
+ public static Suggestion<? extends Entry<? extends Option>> fromXContent(XContentParser parser) throws IOException {
+ ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
+ String typeAndName = parser.currentName();
+ // we need to extract the type prefix from the name and throw error if it is not present
+ int delimiterPos = typeAndName.indexOf(InternalAggregation.TYPED_KEYS_DELIMITER);
+ String type = null;
+ String name = null;
+ if (delimiterPos > 0) {
+ type = typeAndName.substring(0, delimiterPos);
+ name = typeAndName.substring(delimiterPos + 1);
+ } else {
+ throw new ParsingException(parser.getTokenLocation(),
+ "Cannot parse suggestion response without type information. Set [" + RestSearchAction.TYPED_KEYS_PARAM
+ + "] parameter on the request to ensure the type information is added to the response output");
+ }
+ Suggestion suggestion = null;
+ Function<XContentParser, Entry> entryParser = null;
+ // the "size" parameter and the SortBy for TermSuggestion cannot be parsed from the response, use default values
+ // TODO investigate if we can use NamedXContentRegistry instead of this switch
+ switch (type) {
+ case Suggestion.NAME:
+ suggestion = new Suggestion(name, -1);
+ entryParser = Suggestion.Entry::fromXContent;
+ break;
+ case PhraseSuggestion.NAME:
+ suggestion = new PhraseSuggestion(name, -1);
+ entryParser = PhraseSuggestion.Entry::fromXContent;
+ break;
+ case TermSuggestion.NAME:
+ suggestion = new TermSuggestion(name, -1, SortBy.SCORE);
+ entryParser = TermSuggestion.Entry::fromXContent;
+ break;
+ case CompletionSuggestion.NAME:
+ suggestion = new CompletionSuggestion(name, -1);
+ entryParser = CompletionSuggestion.Entry::fromXContent;
+ break;
+ default:
+ throw new ParsingException(parser.getTokenLocation(), "Unknown suggestion type [{}]", type);
+ }
+ ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.nextToken(), parser::getTokenLocation);
+ while ((parser.nextToken()) != XContentParser.Token.END_ARRAY) {
+ suggestion.addTerm(entryParser.apply(parser));
+ }
+ return suggestion;
+ }
+
/**
* Represents a part from the suggest text with suggested options.
*/
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestion.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestion.java
index 51b44a300d..ed45104d99 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestion.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestion.java
@@ -64,7 +64,7 @@ import static org.elasticsearch.search.suggest.Suggest.COMPARATOR;
*/
public final class CompletionSuggestion extends Suggest.Suggestion<CompletionSuggestion.Entry> {
- private static final String NAME = "completion";
+ public static final String NAME = "completion";
public static final int TYPE = 4;
diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestion.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestion.java
index 3ea0d61d72..fb646b03ae 100644
--- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestion.java
+++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestion.java
@@ -35,7 +35,7 @@ import java.io.IOException;
*/
public class PhraseSuggestion extends Suggest.Suggestion<PhraseSuggestion.Entry> {
- private static final String NAME = "phrase";
+ public static final String NAME = "phrase";
public static final int TYPE = 3;
public PhraseSuggestion() {
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 5f6cd310ad..31621fb63b 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
@@ -41,7 +41,7 @@ import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constru
*/
public class TermSuggestion extends Suggestion<TermSuggestion.Entry> {
- private static final String NAME = "term";
+ public static final String NAME = "term";
public static final Comparator<Suggestion.Entry.Option> SCORE = new Score();
public static final Comparator<Suggestion.Entry.Option> FREQUENCY = new Frequency();