Skip to content

Instantly share code, notes, and snippets.

@cxxr
Last active August 29, 2015 14:04
Show Gist options
  • Save cxxr/5dc1977acd9e10d174bc to your computer and use it in GitHub Desktop.
Save cxxr/5dc1977acd9e10d174bc to your computer and use it in GitHub Desktop.
How to search Elasticsearch, with a good code contract
package me.seancassidy.search;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchTimeoutException;
import org.elasticsearch.action.ListenableActionFuture;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.TimeValue;
import java.util.concurrent.TimeoutException;
public class SearchES {
private static final Gson gson = new GsonBuilder()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.create();
private final Client esClient;
private final long timeout; // in milliseconds
/**
* Creates an easy-to-use interface to searching Elasticsearch
*
* @param esClient The Elasticsearch Client to use
* @param timeout How long, in millseconds, should each query take at most
*/
public SearchES(Client esClient, long timeout) {
this.esClient = esClient;
this.timeout = timeout;
}
/**
* Searches Elasticsearch with the given query.
*
* @param query The JSON query to search with
* @return The SearchResponse returned from Elasticsearch
* @throws TimeoutException When the query takes longer than this.timeout (milliseconds)
* @throws IllegalArgumentException When the query is malformatted or when no indices are specified
* @throws ElasticsearchException Thrown from Elasticsearch directly
*/
public SearchResponse search(JsonElement query, String... indices)
throws TimeoutException, IllegalArgumentException, ElasticsearchException {
if (indices.length < 1) {
throw new IllegalArgumentException("Must specify at least one index");
}
try {
final ListenableActionFuture<SearchResponse> searchFuture =
esClient.prepareSearch(indices)
.setQuery(gson.toJson(query))
.setTimeout(new TimeValue(timeout))
.execute();
return searchFuture.actionGet(timeout + 100);
} catch (SearchPhaseExecutionException e) {
if ("query".equalsIgnoreCase(e.phaseName())) {
throw new IllegalArgumentException("Badly formatted query", e);
}
throw e;
} catch (ElasticsearchTimeoutException e) {
throw new TimeoutException(e.getMessage());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment