【问题标题】:Extract the Source data from Elastic Search Suggest Search response using JAVA API使用 JAVA API 从 Elastic Search Suggest Search 响应中提取源数据
【发布时间】:2020-09-23 07:39:50
【问题描述】:

我在 Java 中将 Completition 建议器用于自动完成应用程序,我能够使用 JAVA api 从搜索响应中提取建议文本。在检查原始响应时,我看到建议响应包含 _source 数据(完整文档而不仅仅是 Suggest 字符串)。如何从 Suggest Search 响应中提取源数据?

请在下面找到我用来获取建议文本的代码 -

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());
  }
}

在选项中,很少有方法可用于提取分数、文本和突出显示。是否可以从选项中获取 _source 数据?我看到了一个 toXContent 函数,是否可以使用它来获取源数据?

sn-p 上面是将建议的字符串保存到一个列表中,我想知道是否有可能获得完整的 Doc JSON。

【问题讨论】:

    标签: java elasticsearch search


    【解决方案1】:

    您可以使用 Elasticsearch 的官方 java 客户端 JHLRC (java high level rest client) 的fetch source API

    根据链接

    此 API 有助于仅获取文档的 _source 字段。

    您可以从之前的回复中获取 id,然后用于获取这些文档的来源。

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

    在 Elastic and 的示例上方,其中 posts 是索引名称,1 是文档 ID。

    【讨论】:

    • 问题是我必须使用 Completition sugester 这不是一个正常的 Id 获取请求。我认为它需要是一个搜索请求。
    • @ted,我假设您的完成建议正在返回包含您的建议的 ID,然后使用我的源 API,您可以通过传递您在第一步中获得的 ID 来获取 _Source 字段,如果我在这里遗漏了什么,请纠正我,你也在使用 JHLRC 吗?
    • 哦,对不起,我误解了你的意思。完成建议器实际上是通过 API 返回文本(文本建议)。我检查了原始响应,我可以看到整个文档是从弹性搜索返回的。所以我想知道是否可以在不发出另一个服务器请求的情况下提取该数据
    • @ted,是的,如果您使用的是 JHLRC,应该告诉我,如果您可以提供完整的代码,我可以提供,否则我可以提供一些示例代码
    • @ted 您似乎正在使用应该避免的传输客户端。取而代之的是 Prerna 提到的JHLRC。使用与您的弹性集群相同的版本。
    【解决方案2】:

    您始终可以使用源过滤来过滤要在搜索结果中返回的字段。在弹性中,您可以在_source 上下文中添加includesexcludes 或两者。例如您只想获取field1field2,您可以将_source 与查询一起设置如下:

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

    使用高级别的客户端也可以实现如下:

    String[] includes = {"field1", "field2"};
    searchSourceBuilder.fetchSource(new FetchSourceContext(true, includes, null));
    

    【讨论】:

    • 通过这种方式我们可以指定哪些源需要被排除和包含。但我的问题是如何从 searchResponse 中获取它。在查询的情况下,我们可以遍历“命中”并使用getSourceAsString 读取它。但我想知道如何在建议响应案例中做到这一点。谢谢
    【解决方案3】:

    我通过将Suggest.Suggestion.Entry.Option 转换为它的实现CompletionSuggestion.Entry.Option 实现了这个技巧,它暴露了SearchHit。以下只是将源映射到您的对象。

    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 是您要映射到的类。

    【讨论】:

      猜你喜欢
      • 2015-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多