1
votes

I'm locked in a trap with Elastic, trying to sort hits by the size of a sub-property (array).

I applied the following body query :

'{
"query": {
    "match_all": {}
},
"sort": {
    "_script": {
        "type": "number",
        "script": "doc[\"myarray\"].values.size()",
        "order": "desc"
    }
}

}'

However as Elastic Array type isn't in the mapping (support out of the box) i have an error telling me that my array isn't the mapping (normal...)

Any idea ?

Thanks !

2

2 Answers

0
votes

The best and recommended way of doing this is to index in the same document an additional field that should include the field size as a number, since this is known at indexing time. And then just sort on that field.

The difficulty of the apparently simple task you want to achieve is that the array in Elasticsearch is considered a flat data structure and everything is just "combined". If you also are using an analyzer on this field that potentially will split the field into terms, do you count the number of unique terms or the values that you indexed initially?

For example, let's say myarray is like ["abc 123", "abc", "123", "abc abc"]. Do you count the comma separated values (4 values in total) or the unique terms (abc and 123 so only 2 values in total)?

The correct and most efficient way of doing this is by indexing the length itself in the documents:

{ "myarray":["abc 123", "abc", "123", "abc abc"], "myarray_length":4 }

0
votes

if you want the array's size then you have use dynamic scripting offered from elastic search. https://www.elastic.co/guide/en/elasticsearch/reference/2.3/modules-scripting.html (choose your version). If you use AWS for hosting ES please do read this https://kirankoduru.github.io/elasticsearch/moving-from-aws-elasticsearch-service.html

And andrei-stefan is correct you can make use of multi field as type when mapping