I am prototyping an app that leverages ES' geospatial search
capabilities, and I'm encountering an error when sorting results by
geo_distance. I'm hoping that I'm simply doing something incorrectly,
but was looking for some direction. The ClassCast stacktrace is
below, along with a unit test that replicates this behavior.
Any guidance/advice would be greatly appreciated.
--stack trace--
org.elasticsearch.action.search.SearchPhaseExecutionException: Failed
to execute phase [query], total failure; shardFailures
{RemoteTransportException[[Blazing Skull][inet[/10.0.1.5:9301]][search/
phase/query]]; nested:
ClassCastException[org.elasticsearch.index.search.geo.GeoDistanceDataComparator
$InnerSource cannot be cast to
org.elasticsearch.index.field.data.FieldDataType
$ExtendedFieldComparatorSource]; }{RemoteTransportException[[Blazing
Skull][inet[/10.0.1.5:9301]][search/phase/query]]; nested:
ClassCastException[org.elasticsearch.index.search.geo.GeoDistanceDataComparator
$InnerSource cannot be cast to
org.elasticsearch.index.field.data.FieldDataType
$ExtendedFieldComparatorSource]; }{RemoteTransportException[[Blazing
Skull][inet[/10.0.1.5:9301]][search/phase/query]]; nested:
ClassCastException[org.elasticsearch.index.search.geo.GeoDistanceDataComparator
$InnerSource cannot be cast to
org.elasticsearch.index.field.data.FieldDataType
$ExtendedFieldComparatorSource]; }{RemoteTransportException[[Blazing
Skull][inet[/10.0.1.5:9301]][search/phase/query]]; nested:
ClassCastException[org.elasticsearch.index.search.geo.GeoDistanceDataComparator
$InnerSource cannot be cast to
org.elasticsearch.index.field.data.FieldDataType
$ExtendedFieldComparatorSource]; }{RemoteTransportException[[Blazing
Skull][inet[/10.0.1.5:9301]][search/phase/query]]; nested:
ClassCastException[org.elasticsearch.index.search.geo.GeoDistanceDataComparator
$InnerSource cannot be cast to
org.elasticsearch.index.field.data.FieldDataType
$ExtendedFieldComparatorSource]; }
at org.elasticsearch.action.search.type.TransportSearchTypeAction
$BaseAsyncAction.onFirstPhaseResult(TransportSearchTypeAction.java:
257)
at org.elasticsearch.action.search.type.TransportSearchTypeAction
$BaseAsyncAction$3.onFailure(TransportSearchTypeAction.java:210)
at org.elasticsearch.search.action.SearchServiceTransportAction
$2.handleException(SearchServiceTransportAction.java:151)
at
org.elasticsearch.transport.netty.MessageChannelHandler.handleException(MessageChannelHandler.java:
158)
at
org.elasticsearch.transport.netty.MessageChannelHandler.handlerResponseError(MessageChannelHandler.java:
149)
at
org.elasticsearch.transport.netty.MessageChannelHandler.messageReceived(MessageChannelHandler.java:
101)
at
org.elasticsearch.common.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:
80)
at
org.elasticsearch.common.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:
545)
at org.elasticsearch.common.netty.channel.DefaultChannelPipeline
$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:
754)
at
org.elasticsearch.common.netty.channel.Channels.fireMessageReceived(Channels.java:
302)
at
org.elasticsearch.common.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:
317)
at
org.elasticsearch.common.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:
299)
at
org.elasticsearch.common.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:
216)
at
org.elasticsearch.common.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:
80)
at
org.elasticsearch.common.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:
545)
at
org.elasticsearch.common.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:
540)
at
org.elasticsearch.common.netty.channel.Channels.fireMessageReceived(Channels.java:
274)
at
org.elasticsearch.common.netty.channel.Channels.fireMessageReceived(Channels.java:
261)
at
org.elasticsearch.common.netty.channel.socket.nio.NioWorker.read(NioWorker.java:
349)
at
org.elasticsearch.common.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:
280)
at
org.elasticsearch.common.netty.channel.socket.nio.NioWorker.run(NioWorker.java:
200)
at
org.elasticsearch.common.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:
108)
at org.elasticsearch.common.netty.util.internal.DeadLockProofWorker
$1.run(DeadLockProofWorker.java:44)
at java.util.concurrent.ThreadPoolExecutor
$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor
$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
--end stack trace--
--unit test--
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.node.NodeBuilder.nodeBuilder;
import static
org.elasticsearch.search.sort.SortBuilders.geoDistanceSort;
import org.elasticsearch.action.count.CountResponse;
import org.elasticsearch.client.Client;
import
org.elasticsearch.client.action.admin.indices.create.CreateIndexRequestBuilder;
import org.elasticsearch.client.action.bulk.BulkRequestBuilder;
import org.elasticsearch.client.action.search.SearchRequestBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.node.Node;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class SortTest {
private static Node node = null;
private static final String INDEX = "sorttest";
private static final String TYPE = "testtype";
@Test
public void testSort() {
SearchRequestBuilder sb = node.client().prepareSearch(INDEX);
sb.setQuery(termQuery("name", "kimchy"));
sb.addSort(geoDistanceSort("location").point(43.12, -73.34));
sb.execute().actionGet();
}
@BeforeClass
public static void setup() throws Exception {
node = nodeBuilder().client(true).node();
CreateIndexRequestBuilder requestBuilder =
node.client().admin().indices().prepareCreate(INDEX);
requestBuilder.addMapping(TYPE,
XContentFactory.jsonBuilder().startObject().startObject(TYPE).startObject("properties").startObject("location").field("type",
"geo_point").endObject().endObject().endObject());
requestBuilder.execute().actionGet();
if (loadData() == false) {
throw new IllegalStateException("Loaded data not searchable?");
}
}
private static boolean loadData() throws Exception {
Client client = node.client();
BulkRequestBuilder b = node.client().prepareBulk();
b.add(client.prepareIndex(INDEX, TYPE, "1").setSource("{\"name\":
"kimchy","color": "red", "pin" : {"location" :
"41.12,-71.34"}}"));
b.add(client.prepareIndex(INDEX, TYPE, "2").setSource("{"name":
"kimchy","color": "blue", "pin" : {"location" :
"42.12,-72.34"}}"));
b.execute().actionGet();
int execCount = 0;
while (execCount < 10) {
CountResponse response =
node.client().prepareCount(INDEX).setQuery(termQuery("name",
"kimchy")).execute().actionGet();
if (response.count() > 0) {
return true;
} else {
Thread.currentThread().sleep(1000);//wait for docs to be indexed
}
}
return false;
}
@AfterClass
public static void tearDown() throws Exception {
node.client().admin().indices().prepareDelete(INDEX).execute().actionGet();
}
}
--end unit test--