minor cleanup suggest api

- make sure we close the parser
- fail when no content is provided in the rest request
- reuse the suggest parse element
This commit is contained in:
Shay Banon 2013-03-13 12:18:14 -07:00
parent 25bd9cecd0
commit 91c51ef05c
4 changed files with 56 additions and 60 deletions

View File

@ -19,8 +19,6 @@
package org.elasticsearch.action.suggest;
import java.io.IOException;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.broadcast.BroadcastOperationRequestBuilder;
@ -32,25 +30,27 @@ import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilder.SuggestionBuilder;
import java.io.IOException;
/**
* A suggest action request builder.
*/
public class SuggestRequestBuilder extends BroadcastOperationRequestBuilder<SuggestRequest, SuggestResponse, SuggestRequestBuilder> {
final SuggestBuilder suggest = new SuggestBuilder();
public SuggestRequestBuilder(Client client) {
super((InternalClient) client, new SuggestRequest());
}
/**
* Add a definition for suggestions to the request
* Add a definition for suggestions to the request
*/
public <T> SuggestRequestBuilder addSuggestion(SuggestionBuilder<T> suggestion) {
suggest.addSuggestion(suggestion);
return this;
}
/**
* A comma separated list of routing values to control the shards the search will be executed on.
*/
@ -58,12 +58,12 @@ public class SuggestRequestBuilder extends BroadcastOperationRequestBuilder<Sugg
request.routing(routing);
return this;
}
public SuggestRequestBuilder setSuggestText(String globalText) {
this.suggest.setText(globalText);
return this;
}
/**
* Sets the preference to execute the search. Defaults to randomize across shards. Can be set to
* <tt>_local</tt> to prefer local shards, <tt>_primary</tt> to execute only on primary shards,
@ -87,9 +87,8 @@ public class SuggestRequestBuilder extends BroadcastOperationRequestBuilder<Sugg
protected void doExecute(ActionListener<SuggestResponse> listener) {
try {
XContentBuilder builder = XContentFactory.contentBuilder(SuggestRequest.contentType);
XContentBuilder content = suggest.toXContent(builder, ToXContent.EMPTY_PARAMS);
content.close();
request.suggest(content.bytes());
suggest.toXContent(builder, ToXContent.EMPTY_PARAMS);
request.suggest(builder.bytes());
} catch (IOException e) {
throw new ElasticSearchException("Unable to build suggestion request", e);
}

View File

@ -19,14 +19,6 @@
package org.elasticsearch.action.suggest;
import static com.google.common.collect.Lists.newArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReferenceArray;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.action.ShardOperationFailedException;
@ -49,14 +41,21 @@ import org.elasticsearch.index.service.IndexService;
import org.elasticsearch.index.shard.service.IndexShard;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestParseElement;
import org.elasticsearch.search.suggest.SuggestPhase;
import org.elasticsearch.search.suggest.SuggestionSearchContext;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReferenceArray;
import static com.google.common.collect.Lists.newArrayList;
/**
* Defines the transport of a suggestion request across the cluster
* Defines the transport of a suggestion request across the cluster
*/
public class TransportSuggestAction extends TransportBroadcastOperationAction<SuggestRequest, SuggestResponse, ShardSuggestRequest, ShardSuggestResponse> {
@ -66,7 +65,7 @@ public class TransportSuggestAction extends TransportBroadcastOperationAction<Su
@Inject
public TransportSuggestAction(Settings settings, ThreadPool threadPool, ClusterService clusterService, TransportService transportService,
IndicesService indicesService) {
IndicesService indicesService) {
super(settings, threadPool, clusterService, transportService);
this.indicesService = indicesService;
this.suggestPhase = new SuggestPhase(settings);
@ -142,7 +141,7 @@ public class TransportSuggestAction extends TransportBroadcastOperationAction<Su
successfulShards++;
}
}
return new SuggestResponse(new Suggest(Suggest.reduce(groupedSuggestions)), shardsResponses.length(), successfulShards, failedShards, shardFailures);
}
@ -151,26 +150,26 @@ public class TransportSuggestAction extends TransportBroadcastOperationAction<Su
IndexService indexService = indicesService.indexServiceSafe(request.index());
IndexShard indexShard = indexService.shardSafe(request.shardId());
final Engine.Searcher searcher = indexShard.searcher();
XContentParser parser = null;
try {
BytesReference suggest = request.suggest();
if (suggest != null && suggest.length() > 0) {
final SuggestParseElement element = new SuggestParseElement();
final XContentParser parser = XContentFactory.xContent(suggest).createParser(suggest);
if(parser.nextToken() != XContentParser.Token.START_OBJECT) {
throw new ElasticSearchIllegalArgumentException("Object expected");
parser = XContentFactory.xContent(suggest).createParser(suggest);
if (parser.nextToken() != XContentParser.Token.START_OBJECT) {
throw new ElasticSearchIllegalArgumentException("suggest content missing");
}
final SuggestionSearchContext context = element.parseInternal(parser, indexService.mapperService());
final SuggestionSearchContext context = suggestPhase.parseElement().parseInternal(parser, indexService.mapperService());
final Suggest result = suggestPhase.execute(context, searcher.reader());
return new ShardSuggestResponse(request.index(), request.shardId(), result);
}
return new ShardSuggestResponse(request.index(), request.shardId(), new Suggest());
} catch(Throwable ex) {
throw new ElasticSearchException("Failed to execute suggest", ex);
} catch (Throwable ex) {
throw new ElasticSearchException("failed to execute suggest", ex);
} finally {
searcher.release();
if (parser != null) {
parser.close();
}
}
}
}

View File

@ -19,34 +19,29 @@
package org.elasticsearch.rest.action.suggest;
import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.POST;
import static org.elasticsearch.rest.RestStatus.BAD_REQUEST;
import static org.elasticsearch.rest.RestStatus.OK;
import static org.elasticsearch.rest.action.support.RestActions.buildBroadcastShardsHeader;
import java.io.IOException;
import org.elasticsearch.ElasticSearchIllegalArgumentException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.suggest.SuggestRequest;
import org.elasticsearch.action.suggest.SuggestResponse;
import org.elasticsearch.action.support.IgnoreIndices;
import org.elasticsearch.action.support.broadcast.BroadcastOperationThreading;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.rest.BaseRestHandler;
import org.elasticsearch.rest.RestChannel;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.XContentRestResponse;
import org.elasticsearch.rest.XContentThrowableRestResponse;
import org.elasticsearch.rest.*;
import org.elasticsearch.rest.action.support.RestActions;
import org.elasticsearch.rest.action.support.RestXContentBuilder;
import org.elasticsearch.search.suggest.Suggest;
import java.io.IOException;
import static org.elasticsearch.rest.RestRequest.Method.GET;
import static org.elasticsearch.rest.RestRequest.Method.POST;
import static org.elasticsearch.rest.RestStatus.BAD_REQUEST;
import static org.elasticsearch.rest.RestStatus.OK;
import static org.elasticsearch.rest.action.support.RestActions.buildBroadcastShardsHeader;
/**
*
*/
@ -82,10 +77,7 @@ public class RestSuggestAction extends BaseRestHandler {
if (source != null) {
suggestRequest.suggest(source);
} else {
BytesReference querySource = RestActions.parseQuerySource(request);
if (querySource != null) {
suggestRequest.suggest(querySource, false);
}
throw new ElasticSearchIllegalArgumentException("no content or source provided to execute suggestion");
}
}
suggestRequest.routing(request.param("routing"));
@ -109,7 +101,7 @@ public class RestSuggestAction extends BaseRestHandler {
buildBroadcastShardsHeader(builder, response);
Suggest suggest = response.getSuggest();
if (suggest != null) {
suggest.toXContent(builder, request);
suggest.toXContent(builder, request);
}
builder.endObject();
channel.sendResponse(new XContentRestResponse(request, OK, builder));

View File

@ -18,11 +18,7 @@
*/
package org.elasticsearch.search.suggest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.util.CharsRef;
import org.elasticsearch.ElasticSearchException;
@ -37,24 +33,34 @@ import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry;
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option;
import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
*/
public class SuggestPhase extends AbstractComponent implements SearchPhase {
private final SuggestParseElement parseElement;
@Inject
public SuggestPhase(Settings settings) {
super(settings);
this.parseElement = new SuggestParseElement();
}
@Override
public Map<String, ? extends SearchParseElement> parseElements() {
ImmutableMap.Builder<String, SearchParseElement> parseElements = ImmutableMap.builder();
parseElements.put("suggest", new SuggestParseElement());
parseElements.put("suggest", parseElement);
return parseElements.build();
}
public SuggestParseElement parseElement() {
return parseElement;
}
@Override
public void preProcess(SearchContext context) {
}
@ -67,7 +73,7 @@ public class SuggestPhase extends AbstractComponent implements SearchPhase {
}
context.queryResult().suggest(execute(suggest, context.searcher().getIndexReader()));
}
public Suggest execute(SuggestionSearchContext suggest, IndexReader reader) {
try {
CharsRef spare = new CharsRef(); // Maybe add CharsRef to CacheRecycler?