1

Trying to use CompletionSuggester for autocomplete feature, There are different ways to implement the completion-suggester through Java's RestHighLevelClient, Wanted to understand is there any difference (in terms of performance/query execution speed) among these below methods

1: Using CompletionSuggestionBuilder (taking 8mill-sec):

val completionSuggestionBuilder = SuggestBuilders.completionSuggestion("field_name").prefix("ban", Fuzziness.ONE).size(10)
        
val suggestBuilder = SuggestBuilder().addSuggestion("find_by_prefix", completionSuggestionBuilder)
val searchSourceBuilder = SearchSourceBuilder().suggest(suggestBuilder)
val searchRequest = SearchRequest("locations").source(searchSourceBuilder)
val searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT)

2: Using SimpleQueryString (taking 30mill-sec) :

val query = """{"suggest":{"find_by_prefix":{"prefix":"Ban","completion":{"field":"field_name","size":10,"fuzzy":{"fuzziness":1},"contexts":{"locationType":[{"context":"AREA","boost":1},{"context":"CITY","boost":1}],"geolocation":[{"lon":77.6279354,"lat":12.9331699,"precision":"30km","boost":2}]}}}}}"""
val searchSourceBuilder = SearchSourceBuilder().query(QueryBuilders.simpleQueryStringQuery(query))
val searchRequest = SearchRequest("locations").source(searchSourceBuilder)
val searchResponse = restClient.search(searchRequest, RequestOptions.DEFAULT)

manjunath
  • 91
  • 1
  • 4
  • Since you are executing an operation over the network, anything you do in code is irrelevant and faster by several orders of magnitude than the actual network call. That said: whatever is easier to extend clearer to you, future you and other devs from your team. Personally, I'd go for the builder – knittl May 29 '21 at 08:02

1 Answers1

1

Depending to your application and your needs it may vary and generally in depends to many variable for example the number of shards replication or your index mappings in index level etc, As the place Elastic built on Apache-Lucene generally the leaf or compound queries have better performance for simple usage but if you need complex result the best approach is to use aggregations moreover if you want to handle your query syntax in application level the best approach is to use string native queries as an example if you have spring boot application the best way is to bind and create your string quires instead of using default repositories, Consider below example

    @Query("{\"bool\":" +
            "{\"must\" :" +
            "[" + "" +
            "{\"query_string\":{ \"query\" : \"?0\", \"fields\" : [ \"parentKnowledgeGroupId\" ] }}," +
            "{\"query_string\":{ \"query\" : \"?1\", \"fields\" : [ \"knowledgeGroupId\" ]}}," +
            "{\"query_string\":{ \"query\" : \"?2\", \"fields\" : [ \"content\" ]}}," +
            "{\"query_string\":{ \"query\" : \"?3\", \"fields\" : [ \"courseType\" ]}}," +
            "]" +
            "}" +
            "}")
    ElasticModelSequence SearchCore(@Param("parentKnowledgeGroupId") String parentKnowledgeGroupId,
                                    @Param("knowledgeGroupId") String knowledgeGroupId, @Param("term") String term,
                                    @Param("courseType") ElasticModelSequence.CourseType courseType);

or for simpler ones

    @Query("{\"term\": {\"sequenceId\" : \"?0\"} " + "}")
    ElasticModelSequence findBySequenceId(@Param("SequenceId")String SequenceId);

you just need to add them in you Elasticsearch repository class where it extended from Elasticsearch Repository like

@Repository
public interface YourRepositoryName extends ElasticsearchRepository<yourmodelname, String>

For spring case you may find out more in Here .

Lunatic
  • 1,519
  • 8
  • 24