summaryrefslogtreecommitdiff
path: root/core/src/main/java/org/elasticsearch/search/suggest/completion
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/elasticsearch/search/suggest/completion')
-rw-r--r--core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestion.java72
1 files changed, 66 insertions, 6 deletions
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 e33e421f77..33ff15fbbb 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
@@ -20,23 +20,30 @@ package org.elasticsearch.search.suggest.completion;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.suggest.Lookup;
+import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.text.Text;
+import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.suggest.Suggest;
+import org.elasticsearch.search.suggest.Suggest.Suggestion;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
+import static org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken;
import static org.elasticsearch.search.suggest.Suggest.COMPARATOR;
/**
@@ -197,14 +204,16 @@ public final class CompletionSuggestion extends Suggest.Suggestion<CompletionSug
}
public static class Option extends Suggest.Suggestion.Entry.Option {
- private Map<String, Set<CharSequence>> contexts;
+ private Map<String, Set<CharSequence>> contexts = Collections.emptyMap();
private ScoreDoc doc;
private SearchHit hit;
+ public static final ParseField CONTEXTS = new ParseField("contexts");
+
public Option(int docID, Text text, float score, Map<String, Set<CharSequence>> contexts) {
super(text, score);
this.doc = new ScoreDoc(docID, score);
- this.contexts = contexts;
+ this.contexts = Objects.requireNonNull(contexts, "context map cannot be null");
}
protected Option() {
@@ -240,14 +249,14 @@ public final class CompletionSuggestion extends Suggest.Suggestion<CompletionSug
@Override
protected XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws IOException {
- builder.field("text", getText());
+ builder.field(TEXT.getPreferredName(), getText());
if (hit != null) {
hit.toInnerXContent(builder, params);
} else {
- builder.field("score", getScore());
+ builder.field(SCORE.getPreferredName(), getScore());
}
if (contexts.size() > 0) {
- builder.startObject("contexts");
+ builder.startObject(CONTEXTS.getPreferredName());
for (Map.Entry<String, Set<CharSequence>> entry : contexts.entrySet()) {
builder.startArray(entry.getKey());
for (CharSequence context : entry.getValue()) {
@@ -260,6 +269,58 @@ public final class CompletionSuggestion extends Suggest.Suggestion<CompletionSug
return builder;
}
+ private static ObjectParser<Map<String, Object>, Void> PARSER = new ObjectParser<>("CompletionOptionParser",
+ true, HashMap::new);
+
+ static {
+ SearchHit.declareInnerHitsParseFields(PARSER);
+ PARSER.declareString((map, value) -> map.put(Suggestion.Entry.Option.TEXT.getPreferredName(), value),
+ Suggestion.Entry.Option.TEXT);
+ PARSER.declareFloat((map, value) -> map.put(Suggestion.Entry.Option.SCORE.getPreferredName(), value),
+ Suggestion.Entry.Option.SCORE);
+ PARSER.declareObject((map, value) -> map.put(CompletionSuggestion.Entry.Option.CONTEXTS.getPreferredName(), value),
+ (p,c) -> parseContexts(p), CompletionSuggestion.Entry.Option.CONTEXTS);
+ }
+
+ private static Map<String, Set<CharSequence>> parseContexts(XContentParser parser) throws IOException {
+ Map<String, Set<CharSequence>> contexts = new HashMap<>();
+ while((parser.nextToken()) != XContentParser.Token.END_OBJECT) {
+ ensureExpectedToken(XContentParser.Token.FIELD_NAME, parser.currentToken(), parser::getTokenLocation);
+ String key = parser.currentName();
+ ensureExpectedToken(XContentParser.Token.START_ARRAY, parser.nextToken(), parser::getTokenLocation);
+ Set<CharSequence> values = new HashSet<>();
+ while((parser.nextToken()) != XContentParser.Token.END_ARRAY) {
+ ensureExpectedToken(XContentParser.Token.VALUE_STRING, parser.currentToken(), parser::getTokenLocation);
+ values.add(parser.text());
+ }
+ contexts.put(key, values);
+ }
+ return contexts;
+ }
+
+ public static Option fromXContent(XContentParser parser) {
+ Map<String, Object> values = PARSER.apply(parser, null);
+
+ Text text = new Text((String) values.get(Suggestion.Entry.Option.TEXT.getPreferredName()));
+ Float score = (Float) values.get(Suggestion.Entry.Option.SCORE.getPreferredName());
+ @SuppressWarnings("unchecked")
+ Map<String, Set<CharSequence>> contexts = (Map<String, Set<CharSequence>>) values
+ .get(CompletionSuggestion.Entry.Option.CONTEXTS.getPreferredName());
+ if (contexts == null) {
+ contexts = Collections.emptyMap();
+ }
+
+ SearchHit hit = null;
+ // the option either prints SCORE or inlines the search hit
+ if (score == null) {
+ hit = SearchHit.createFromMap(values);
+ score = hit.getScore();
+ }
+ CompletionSuggestion.Entry.Option option = new CompletionSuggestion.Entry.Option(-1, text, score, contexts);
+ option.setHit(hit);
+ return option;
+ }
+
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
@@ -317,7 +378,6 @@ public final class CompletionSuggestion extends Suggest.Suggestion<CompletionSug
stringBuilder.append("]");
return stringBuilder.toString();
}
-
}
}