Reputation: 25862
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?
Upvotes: 1
Views: 4967
Reputation: 5050
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;
Upvotes: 3