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
This commit is contained in:
Alexander Reelsen 2013-06-27 09:57:06 +02:00
parent 71d5148b1c
commit 0a50ed0a27
1 changed files with 25 additions and 13 deletions

View File

@ -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<String, SuggestionContext> 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<String, SuggestionContext> 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;
}
}