I'm trying to query some properties in a nested object with a script sort
and I'm running into some strange behaviour. I managed to contrive a small
example that reproduces this.
First, create a new index and apply the attached mapping:
curl -X PUT http://localhost:9200/widgets
curl -X PUT http://localhost:9200/widgets/widget/_mapping -d @widget.json
Then add some objects to the index:
curl -X PUT http://localhost:9200/widgets/widget/1 -d
'{"id":1,"type":"pegasus","components":[{"id":1,"type":"honda
civic"},{"id":2,"type":"mazda rx-8"}]}'
curl -X PUT http://localhost:9200/widgets/widget/2 -d
'{"id":2,"type":"pegasus","components":[{"id":1,"type":"honda
accord"},{"id":2,"type":""}]}'
curl -X PUT http://localhost:9200/widgets/widget/3 -d
'{"id":3,"type":"unicorn","components":[{"id":3,"type":"toyota supra"}]}'
curl -X PUT http://localhost:9200/widgets/widget/4 -d
'{"id":4,"type":"unicorn","components":[]}'
I'm trying to find all widgets that have a component with "id" 1 and I want
to sort by the "type" value. Anything without that value should get sorted
to the bottom (I'm using 'Z' for that below, though in practice I use
character '\uffe0'). I use the following script:
ids = doc['components.id'];
if (ids.empty || ids.values.length == 0)
return 'Z';
types = doc['components.type'];
if (!ids.multiValued)
return types.value;
for (i = 0; i < ids.values.length; i++)
if (ids.values[i] == 2)
return type.values[i];
return 'Z';
I'm running it with curl like so:
curl -X GET http://localhost:9200/widgets/widget/_search?pretty -d
'{"sort":{"_script":{"script":"ids=doc['''components.id'''];if(ids.empty||ids.values.length==0)return
'''Z''';type=doc['''components.type'''];if(!ids.multiValued)return
type.value;for(i=0;i<ids.values.length;i++)if(ids.values[i]==2)return
type.values[i];return '''Z''';","type":"string","order":"asc"}}}'
When I run this, some of the shards fail with a ClassCastException (full
stack trace attached):
Caused by: java.lang.ClassCastException: [J cannot be cast to [Ljava.lang.
Object;
at org.elasticsearch.common.mvel2.optimizers.impl.refl.nodes.
ArrayAccessorNest.getValue(ArrayAccessorNest.java:53)
at org.elasticsearch.common.mvel2.optimizers.impl.refl.nodes.
GetterAccessor.getValue(GetterAccessor.java:40)
... 31 more
Any ideas about what I may be doing wrong or how I can fix this? Thanks.
Kamil
--