From 0a50ed0a272e13d78f8329b2b1e469cab1fc6b82 Mon Sep 17 00:00:00 2001 From: Alexander Reelsen Date: Thu, 27 Jun 2013 09:57:06 +0200 Subject: [PATCH] Dont execute suggest before parsing the full request The current implementation of parsing suggestions executed inside of the the pull parser - which resulted in being reliable of the order of the elements in the request. This fix changes the behaviour to parse the relevant parts of the request first and then execute all the suggestions afterwards, so we can be sure that every information has been extracted from the request before execution. Closes #3247 --- .../search/suggest/SuggestParseElement.java | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/elasticsearch/search/suggest/SuggestParseElement.java b/src/main/java/org/elasticsearch/search/suggest/SuggestParseElement.java index 8332e247164..932052da582 100644 --- a/src/main/java/org/elasticsearch/search/suggest/SuggestParseElement.java +++ b/src/main/java/org/elasticsearch/search/suggest/SuggestParseElement.java @@ -18,10 +18,6 @@ */ package org.elasticsearch.search.suggest; -import org.elasticsearch.search.SearchShardTarget; - -import java.io.IOException; - import org.apache.lucene.util.BytesRef; import org.elasticsearch.ElasticSearchIllegalArgumentException; import org.elasticsearch.common.inject.Inject; @@ -31,6 +27,11 @@ import org.elasticsearch.search.SearchParseElement; import org.elasticsearch.search.internal.SearchContext; import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext; +import java.io.IOException; +import java.util.Map; + +import static com.google.common.collect.Maps.newHashMap; + /** * */ @@ -52,6 +53,8 @@ public final class SuggestParseElement implements SearchParseElement { SuggestionSearchContext suggestionSearchContext = new SuggestionSearchContext(); BytesRef globalText = null; String fieldName = null; + Map suggestionContexts = newHashMap(); + XContentParser.Token token; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { @@ -65,6 +68,7 @@ public final class SuggestParseElement implements SearchParseElement { } else if (token == XContentParser.Token.START_OBJECT) { String suggestionName = fieldName; BytesRef suggestText = null; + SuggestionContext suggestionContext = null; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { @@ -83,19 +87,27 @@ public final class SuggestParseElement implements SearchParseElement { throw new ElasticSearchIllegalArgumentException("Suggester[" + fieldName + "] not supported"); } final SuggestContextParser contextParser = suggesters.get(fieldName).getContextParser(); - SuggestionContext suggestion = contextParser.parse(parser, mapperService); - suggestion.setText(suggestText); - suggestion.setShard(shardId); - suggestion.setIndex(index); - SuggestUtils.verifySuggestion(mapperService, globalText, suggestion); - suggestionSearchContext.addSuggestion(suggestionName, suggestion); + suggestionContext = contextParser.parse(parser, mapperService); } } + if (suggestionContext != null) { + suggestionContext.setText(suggestText); + suggestionContexts.put(suggestionName, suggestionContext); + } + } } + + for (Map.Entry entry : suggestionContexts.entrySet()) { + String suggestionName = entry.getKey(); + SuggestionContext suggestionContext = entry.getValue(); + + suggestionContext.setShard(shardId); + suggestionContext.setIndex(index); + SuggestUtils.verifySuggestion(mapperService, globalText, suggestionContext); + suggestionSearchContext.addSuggestion(suggestionName, suggestionContext); + } + return suggestionSearchContext; } - - - }