I've been tasked to upgrade code from RestHighLevelClient to the ES 8 Java Client. Most of it has been pretty smooth, until I got to our CompletionSuggestion code.
When the user starts typing in the search field, we present them with a list of possible search terms to use, based on results returned from the above "suggest" field.
Our current code:
List<String> result = new ArrayList<>();
CompletionSuggestionBuilder csb = new CompletionSuggestionBuilder("suggest");
csb.text(query).size(100); // query is the incoming search text
SearchSourceBuilder ssb = new SearchSourceBuilder();
SearchRequest sr = new SearchRequest(index);
ssb.suggest(new SuggestBuilder()
.addSuggestion("Suggestion", csb));
sr.source(ssb);
SearchResponse resp = rhlClient.search(sr, RequestOptions.DEFAULT);
if (resp.getSuggest().size() == 0) {
return result;
}
Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> suggestionBldr = resp.getSuggest().getSuggestion("Suggestion");
Iterator<? extends Suggest.Suggestion.Entry.Option> iterator =
suggestionBldr.iterator().next().getOptions().iterator();
// We then just loop through the iterator and build the result
I have tried using the new CompletionSuggester, along with other new options, but each tutorial or how-to I've seen/attempted returns a list of the the full records, not a list of search terms like we were getting before.
How can I get the Java Client to return a list of suggested terms, instead of the full record?
Hello and welcome!
Yes the new CompletionSuggester is a bit convoluted in terms of usage, to map it as precisely as possible to the various responses the server can send we relied heavily on generics, thus the complexity of retrieving the results - we'll try to make it easier in the future.
I implemented the Completion Suggester example in the documentation with the new java client, and it seems to be working as expected, here is the code for the search:
SearchResponse suggestResponse = esClient.search(s -> s
.index("music")
.suggest(su -> su
.suggesters("song-suggest", sg -> sg
.completion(c -> c
.field("suggest"))
.prefix("nir"))), MusicSuggest.class);
MusicSuggest is a custom class created to map this document:
of course imagine the lists being streamed/iterated instead of just reading the first value, but this should give an idea on how to proceed. Let me know if it works for your case!
Hello Laura. Thank you for the response and suggestions. I was able to get this solution implemented and functioning, however it still isn't getting me what I need.
I'm getting a set of entire records, of which "suggest" is just one of many fields on each record. When I go through the results as you've indicated, I'm presented with the entire list of "suggest:input" strings.
In your example, when using a prefix of "nir", I am needing only "Nirvana" to be returned. What I'm getting is the entire record, with the .getSuggest().getInput() returning ["Nevermind","Nirvana"].
I can point you to exactly what I am needing because our old RestHighLevelClient code is out for the world to see. If you go to NRD and start typing in the search field, you will see a list of up to 5 possible suggestions on what you might want to search for.
I decided trying out the search directly in Kibana to see if I could figure out what search settings will return what I needed. Lo and behold, I found the solution!
The documentation, along with Laura's help, was almost exactly right. The problem was in retrieving the results. What I needed was not in this:
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.