1

I am using the Completition suggester for an auto complete App in Java, I was able to extract the suggest text from the Search response using the JAVA api. While checking the raw response I saw that suggest response contain the _source data (complete document instead of just the Suggest string). How to extract the source data from the Suggest Search response ?

Please find below the Code I have used to get the suggested text -

SearchRequest searchRequest = new SearchRequest("my_entitiy");
CompletionSuggestionBuilder suggestionBuilder = new CompletionSuggestionBuilder("nameSuggest");
suggestionBuilder.size(10).prefix(input).skipDuplicates(true);

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.suggest(
        new SuggestBuilder().addSuggestion(SUGGESTION_NAME, suggestionBuilder));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = elasticClient.search(searchRequest, RequestOptions.DEFAULT);

Suggest suggest = searchResponse.getSuggest();
Suggest.Suggestion<Suggest.Suggestion.Entry<Suggest.Suggestion.Entry.Option>> suggesition =
        suggest.getSuggestion(SUGGESTION_NAME);
List<String> suggestionList =  new ArrayList<>();
for (Suggest.Suggestion.Entry<Suggest.Suggestion.Entry.Option> entry : suggesition.getEntries()) {
  for(Suggest.Suggestion.Entry.Option option:entry.getOptions()){
    suggestionList.add(option.getText().toString());
  }
}

In the Option few methods are available to extract the score, text and highlighted. Is it possible to get the _source data from the option ? I saw a toXContent function is it possible to use that to get the source data ?

Above snippet is saving the Suggested string to a list I was wondering whether it's possible to get the complete Doc JSON.

ted
  • 3,911
  • 3
  • 26
  • 49

3 Answers3

0

You can use the fetch source API of JHLRC (java high level rest client) which is the official java client of Elasticsearch.

As per the link

This API helps to get only the _source field of a document.

You can get the id from your previous response and then use to get the source of those documents.

GetSourceRequest getSourceRequest = new GetSourceRequest(
    "posts", 
    "1"); 

Above the sample from Elastic and , where posts is the index name and 1 is the doc id.

  • The issue is I have to use the Completition sugester it's not a normal Id Get Request. I think it need to be a Search Request. – ted Jun 04 '20 at 11:23
  • @ted, I am assuming your completion suggetor is returning the ids which contains your suggestions and after that using my source API you can fetch the `_Source` field by passing the ids which you get in first step, correct me if I am missing something here, also are you using JHLRC? –  Jun 04 '20 at 11:25
  • Oh Sorry I misunderstood what you said. Completion suggestor is returning the Text actually (Text Suggestions) via the API. I checked the Raw response and I can see that whole document is returned from Elastic search. So I was wondering it's possible to extract that data without making another Server request – ted Jun 04 '20 at 11:55
  • @ted, yeah then it should be let me know if you are using JHLRC and I would be able to provide that if you can provide your complete code, otherwise I can provide some sample code –  Jun 04 '20 at 12:04
  • I am new to the library. I am not sure about the name JHLRC - I am using the Library based on this Document - https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/index.html. I will modify the code snippet – ted Jun 04 '20 at 12:29
  • @ted can you share pom.xml or the Jar name of which correspond to this code, JHLRC as mentioned in my answer is java high level rest client and link to that also mentioned in answer –  Jun 04 '20 at 13:11
  • 1
    @ted you seem to be using transport client which should be avoided. Instead you the [JHLRC](https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html) as mentioned by Prerna. Us the version same as that is of your elastic cluster. – Nishant Jun 04 '20 at 14:01
  • I am sorry I think I posted the wrong Documentation link - from my JAR - org.elasticsearch.client:elasticsearch-rest-high-level-client:7.1.0. This is the lib I am using – ted Jun 04 '20 at 16:38
  • @ted could you please upvote and accept the answer if answer and discussion was helpful to you. –  Jun 05 '20 at 15:24
  • @PrernaGupta Sorry Answer dint help me with my query. I hope you understand – ted Jun 05 '20 at 16:07
  • @ted, wasn't even useful ? you can upvote if it was helpful, I am ok you not accepting as I understand its not what you are looking for, what about other answer did it help you? –  Jun 05 '20 at 17:40
  • It's right information/fact in this answer which I know but was not related to what I was looking. The other answer also was not really helpful, I have commented in that answer. It was talking about the "query" query. I was looking how to get the data from "suggest" query. I know that API is fetching data(source) from elastic search what I don't know is how to take it from search response. – ted Jun 07 '20 at 18:59
0

You can always make use of source filtering to filter the fields to be returned in search results. In elastic you can do so adding includes, excludes or both in _source context. For e.g. you want only to get field1 and field2, the you can set the _source as below along with query:

{
  "query":{
    // your query goes here
  },
  "_source":{
    "includes":["field1", "field2"]
  }
}

Using high level rest client the same can be achieved as below:

String[] includes = {"field1", "field2"};
searchSourceBuilder.fetchSource(new FetchSourceContext(true, includes, null));
Nishant
  • 7,504
  • 1
  • 21
  • 34
  • In this way we can specify which source need to be excludes and includes. But my question was how to get it from the searchResponse. In case of query we can traverse "hits" and read it using `getSourceAsString`. But I was wondering how to do it in the Suggestion response case. Thanks – ted Jun 05 '20 at 13:38
0

I did the trick by converting Suggest.Suggestion.Entry.Option to its implementation CompletionSuggestion.Entry.Option which exposed SearchHit. The following thing is just to map source to your object.

CompletionSuggestion.Entry.Option completionSuggestionEntryOption =
              (CompletionSuggestion.Entry.Option) option;
          SearchHit searchHit = completionSuggestionEntryOption.getHit();
          String hitJson = searchHit.getSourceAsString();
          ObjectMapper objectMapper = new ObjectMapper();
          T object = objectMapper.readValue(hitJson, clazz);

clazz is the class you want to map to.