Search code examples
elasticsearchelasticsearch-high-level-restclient

Sorting in elastic search using new java api


I am using the latest java API for communication with the elastic search server.

I require to search data in some sorted order.

       SortOptions sort = new SortOptions.Builder().field(f -> f.field("customer.keyword").order(SortOrder.Asc)).build();
    List<SortOptions> list = new ArrayList<SortOptions>();
    list.add(sort);

    SearchResponse<Order> response = elasticsearchClient.search(b -> b.index("order").size(100).sort(list)
            .query(q -> q.bool(bq -> bq
                    .filter(fb -> fb.range(r -> r.field("orderTime").
                                    gte(JsonData.of(timeStamp("01-01-2022-01-01-01")))
                                    .lte(JsonData.of(timeStamp("01-01-2022-01-01-10")))
                            )
                    )
                   // .must(query)
            )), Order.class);

I have written the above code for getting search results in sorted order by customer. I am getting the below error when I run the program.

Exception in thread "main" co.elastic.clients.elasticsearch._types.ElasticsearchException: [es/search] failed: [search_phase_execution_exception] all shards failed
at co.elastic.clients.transport.rest_client.RestClientTransport.getHighLevelResponse(RestClientTransport.java:281)
at co.elastic.clients.transport.rest_client.RestClientTransport.performRequest(RestClientTransport.java:147)
at co.elastic.clients.elasticsearch.ElasticsearchClient.search(ElasticsearchClient.java:1487)
at co.elastic.clients.elasticsearch.ElasticsearchClient.search(ElasticsearchClient.java:1504)
at model.OrderDAO.fetchRecordsQuery(OrderDAO.java:128)

Code runs fine if I remove .sort() method.

My index is configured in the following format.

{
"order": {
    "aliases": {},
    "mappings": {
        "properties": {
            "customer": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "orderId": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },
            "orderTime": {
                "type": "long"
            },
            "orderType": {
                "type": "text",
                "fields": {
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            }
        }
    },
    "settings": {
        "index": {
            "routing": {
                "allocation": {
                    "include": {
                        "_tier_preference": "data_content"
                    }
                }
            },
            "number_of_shards": "1",
            "provided_name": "order",
            "creation_date": "1652783550822",
            "number_of_replicas": "1",
            "uuid": "mrAj8ZT-SKqC43-UZAB-Jw",
            "version": {
                "created": "8010299"
            }
        }
    }
}

}

Please let me know what is wrong here also if possible please send me the correct syntax for using sort() in the new java API.

Thanks a lot.


Solution

  • As you have confirmed in comment, customer is a text type field and this is the reason you are getting above error as sort can not apply on texttype of field.

    Your index should be configured like below for customer field to apply sort:

    {
        "mappings": {
            "properties": {
                "customer": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }
    }
    

    Once you have index mapping like above, you can use customer.keyword as field name for sorting and customer as field name for free text search.