Class Cast when Sorting by geo_distance?

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--

Heya,

Verified as a bug, opened an issue:
Failure to reduce geo distance sorting (class case exception) · Issue #1234 · elastic/elasticsearch · GitHub (will be part of
0.17.5). One quick note, if you write tests, you don't have to write complex
code to wait for the data to be searchable, just issue a refresh request and
it will be searchable.

-shay.banon

On Thu, Aug 11, 2011 at 6:38 PM, Kodos jake.meier@gmail.com wrote:

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--

Brilliant. Thanks!