1

In my Spring Data Elasticsearch application I'd like to implement autocomplete functionality when user types a few chars and application will show him all possible variants with query*.

Right now I can't find a way how to properly implement it with Spring Data Elasticsearch.

For example I tried the following:

Criteria c = new Criteria("name").startsWith(query);
return elasticsearchTemplate.queryForPage(new CriteriaQuery(c, pageRequest), ESDecision.class);

It works for a single word query but in case of two or more words it returns error:

"Cannot constructQuery '*"security windows"'. Use expression or multiple clauses instead."

How to properly implement it in this case?

1 Answer 1

3

I have same requirement , I have implemented same . Querystring will work for you . If you have two token like "security windows" than you have to pass "*security* *windows*" than Querystring will return all possible data available . If you have one token like "security" than you have to pass "*security*" .

One more explaination for this scenario ,check this answer - https://stackoverflow.com/a/43278852/2357869

String aQueryString = "security windows" ;
String aQueryWithPartialSerach = null;
List<ESDecision> aESDecisions = null;


 // Enabling partial sarch
        if (aQueryString.contains(" ")) {
            List<String> aTokenList = Arrays.asList(aQueryString.split(" "));
            aQueryWithPartialSerach = String.join(" ", aTokenList.stream().map(p -> "*" + p + "*").collect(Collectors.toList()));
        } else {
            aQueryWithPartialSerach = "*" + aQueryString + "*";
        }
NativeSearchQueryBuilder aNativeSearchQueryBuilder = new NativeSearchQueryBuilder();
        aNativeSearchQueryBuilder.withIndices(indexName).withTypes(type).withPageable(new PageRequest(0, iPageRequestCount));
        final BoolQueryBuilder aQuery = new BoolQueryBuilder();

            aQuery.must(QueryBuilders.queryStringQuery(aQueryWithPartialSerach).defaultField("name"));

  NativeSearchQuery nativeSearchQuery = aNativeSearchQueryBuilder.withQuery(aQuery).build();
        aESDecisions = elasticsearchTemplate.queryForList(nativeSearchQuery, ESDecision.class);
        return aESDecisions;

Imports need to be done :-

import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.domain.PageRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.