Reputation: 1171
I need to sort in Elasticsearch by parent and nested fields at the same time. My data are like this:
[
{
"id": "1",
"rank": 8,
"price": 12.45,
"offers": [
{
"id": "777",
"rank": 12,
"price": 45.75
}
]
},
{
"id": "2",
"rank": 35,
"price": 5.95,
"offers": null
}
]
I need to sort the results on rank
in such a manner that when the offers
are not null
I should take nested offers.rank
value, otherwise I should take the parent rank
value.
I tried this script, but it did not work:
"sort": [
{
"_script": {
"script": {
"source": "doc['offers'].size()==0 ? doc['rank'].value : doc['offers.rank'].value",
"lang": "painless"
},
"type": "number",
"order": "asc"
}
}
]
It did not work probably because offers.rank
is from a nested offers
object, which is not accessible. But I do not understand how to handle it - if I add a nested condition for the whole script, then my parent value doc['rank'].value
will not be accessible anymore. It is possible to sort here by parent and nested fields at the same time?
Upvotes: 3
Views: 1611
Reputation: 16925
You're right in assuming that the parent rank would not be accessible. Now, you could either
_source
instead:{
"sort": [
{
"_script": {
"script": {
"source": """
if (params._source.offers instanceof ArrayList
&& params._source.offers.length > 0) {
return params._source['offers'][0].rank;
}
return params._source.rank
""",
"lang": "painless"
},
"type": "number",
"order": "asc"
}
}
]
}
Note that since we're working with an 'offers' ArrayList
here, you'll need some sort of mechanism to pick a rank. That's up to you -- I've simply accessed the first offer's rank and you may want to sort the array list & pick the highest one...
Here's a one-liner if that's what you prefer:
params._source.offers instanceof ArrayList && params._source.offers.length > 0 ? params._source['offers'][0].rank : params._source.rank
Upvotes: 3