使用 Java API 的 ElasticSearch 完成建议器

分享于2023年04月15日 elasticsearch java 问答
【问题标题】:ElasticSearch completion suggester with Java API使用 Java API 的 ElasticSearch 完成建议器
【发布时间】:2023-04-08 09:16:01
【问题描述】:

我在网上尝试了一些关于 ElasticSearch 的建议功能的示例代码,但我无法解决自动完成解决方案的问题

我的索引:

client.prepareIndex("kodcucom", "article", "1")
      .setSource(putJsonDocument("ElasticSearch: Java",
        "ElasticSeach provides Java API, thus it executes all operations " +
        "asynchronously by using client object..",
         new Date(),
         new String[]{"elasticsearch"},
         "Hüseyin Akdoğan")).execute().actionGet();

我使用suggestbuilder获取关键字然后扫描内容“字段”,这里是由于没有结果而发生空指针异常的地方

CompletionSuggestionBuilder skillNameSuggest = new CompletionSuggestionBuilder("skillNameSuggest");

skillNameSuggest.text("lien");
skillNameSuggest.field("content");

SuggestRequestBuilder suggestRequestBuilder = client.prepareSuggest("kodcucom").addSuggestion(skillNameSuggest);

SuggestResponse suggestResponse = suggestRequestBuilder.execute().actionGet();

Iterator iterator =
          suggestResponse.getSuggest().getSuggestion("skillNameSuggest").iterator().next().getOptions().iterator();

为了获得结果,我是否遗漏了一些过滤器或输入条件?任何结果都应该没问题,例如自动完成或找到记录。

编辑 1:

这是我获得 NPE 的地方,我可以看到在调试模式下 suggestResponse 处没有返回任何结果

Iterator iterator =
              suggestResponse.getSuggest().getSuggestion("skillNameSuggest").iterator().next().getOptions().iterator();

编辑 2: 我正在使用 2.1.1 版本的 ElasticSearch Java API

编辑 3: 我尝试将迭代器行拆分为几个代码块,将一组数据转换为迭代器时,NPE出现在最后一行,但没有太大帮助

Suggest tempSuggest = suggestResponse.getSuggest();

Suggestion tempSuggestion = tempSuggest.getSuggestion("skillNameSuggest");

Iterator tempIterator = tempSuggestion.iterator();

我看到代码:

SuggestRequestBuilder suggestRequestBuilder = client.prepareSuggest("kodcucom").addSuggestion(skillNameSuggest);

    SuggestResponse suggestResponse = suggestRequestBuilder.execute().actionGet();

已经包含一个空数组/数据集,我是否错误地使用了建议请求生成器?

  • 从哪里获得 NPE(即堆栈跟踪)?
  • 请原谅我是 ES 的新手,什么是 NPE 和 stacktrace?
  • 对不起,NPE 是空指针异常的缩写,即运行 Java 程序时在控制台中出现的错误(=stacktrace)。
  • 我更新了我的问题,谢谢
  • 所以你的意思是 suggestResponse 为空?

【解决方案1】:

为了使用补全功能,您需要指定一个字段,称为补全,您必须为其指定一个特殊的映射。

例如:

"mappings": {
   "article": {
     "properties": {
      "content": {
        "type": "string"
      },
     "completion_suggest": {
      "type": "completion"}
     }
   }
}

completion_suggest 字段是我们将用于上述代码示例中的自动完成功能的字段。在这个映射定义之后,数据必须被索引如下:

curl -XPOST localhost:9200/kodcucom/article/1 -d '{
   "content": "elasticsearch",
   "completion_suggest": {
     "input": [ "es", "elastic", "elasticsearch" ],
     "output": "ElasticSearch"
   }
}'

那么可以使用Java API如下获取建议:

CompletionSuggestionBuilder skillNameSuggest  = new CompletionSuggestionBuilder("complete");
skillNameSuggest.text("es");
skillNameSuggest.field("completion_suggest");

SearchResponse searchResponse = client.prepareSearch("kodcucom")
        .setTypes("article")
        .setQuery(QueryBuilders.matchAllQuery())
        .addSuggestion(skillNameSuggest)
        .execute().actionGet();

CompletionSuggestion compSuggestion = searchResponse.getSuggest().getSuggestion("complete");

List entryList = compSuggestion.getEntries();
if(entryList != null) {
    CompletionSuggestion.Entry entry = entryList.get(0);
    List options =entry.getOptions();
    if(options != null)  {
        CompletionSuggestion.Entry.Option option = options.get(0);
        System.out.println(option.getText().string());
    }
}

【讨论】:

  • 用你的第一个代码块,我怎样才能在java语法中实现呢?
  • CreateIndexRequestBuilder createIndexRequestBuilder = client.admin() .indices().prepareCreate("your_index_name"); XContentBuilder mappingBuilder = jsonBuilder().startObject().startObject("your_type_name").startObject("properties").startObject("your_completion_field").field("type", "completion").endObject().endObject() .endObject().endObject(); createIndexRequestBuilder.addMapping("yoru_index_name", mappingBuilder); createIndexRequestBuilder.execute().actionGet();
  • 谢谢 :) 恰到好处