如何处理多字文本的自动完成?

时间:2017-11-12 15:52:42

标签: elasticsearch autocomplete

我的输入文字是一个多字英文文本,我需要为该文字实现自动完成功能。

我最初查看搜索completion suggesters只是为了弄清楚那些只能匹配输入的第一个字符。这适用于自动完成产品名称或地址,但在输入文本中的任何单词需要自动完成时不是很有用。

之后我设置了一个 edge_ngram 分析器并查询以找到包含输入字符串的那些文档。这很好但我不知道如何使用这些信息为我的自动完成提供选项。

我可以使用highlighter来显示与查询匹配的字词。该数据又可用于设置选项列表。这个解决方案看起来相当hacky并且不是很优雅,我想知道这个问题通常是如何解决的?

遗憾的是,我无法维护另一个可能包含文档自动完成选项的字段。

2 个答案:

答案 0 :(得分:1)

我目前正在使用查询的突出显示信息来构建自动填充选项。

我的查询:

{
  "query": {
    "match": {
      "fields.content.auto": {
        "query": "content co",
        "analyzer": "standard"
      }
    }
  },
  "highlight": {
    "fields": {
      "fields.content.auto": {
        "fragment_size": 0,
        "number_of_fragments": 10,
        "pre_tags" : [ "%ha%" ],
        "post_tags" : [ "%he%" ]
      }
    }
  },
  "_source": ["uuid", "language"]
}

我的自动字段使用了autocomplete分析器。

"auto": {
  "type": "string",   
  "analyzer": "autocomplete"
}

这是我使用的索引配置:

{
  "analysis": {
    "filter": {
      "my_stop": {
        "type":       "stop",
        "stopwords":  "_english_"
      },
      "autocomplete_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 20
      }
    },
    "analyzer": {
      "autocomplete": {
        "type": "custom",
        "tokenizer": "standard",
        "filter": [
          "lowercase",
          "my_stop",
          "autocomplete_filter"
        ]
      }
    }
  }
}

解决方案的主要灵感来自Search-as-you-type帖子。

我处理响应JSON以获取自动完成选项。 突出显示信息用于提取所有找到的令牌。接下来,这些令牌用于构建潜在的自动完成短语,同时将其与用户已输入的短语进行比较。巧妙的是,可以应用停用词过滤器,因此停用词永远不会被突出显示,反过来也不会用于自动完成建议。

可以找到此处理器的PoC Java代码here

我还不确定我是否会使用此解决方案,但无论如何我想分享它。

答案 1 :(得分:0)

我认为您最好的选择是创建一个专用索引,用于使用edge_ngram分析器存储建议。如果您使用完成建议,则无论如何都需要明确定义您的实际建议。完成建议器在ES 5.x中也是以文档为中心的,因此如果您使用相同的建议索引多个文档,您将在匹配时返回重复的建议。 ES 6中有一个重复数据删除选项,但刚刚发布。

如果您有专门的建议索引,则可以使用建议的散列作为文档ID,以避免重复。您可以开始将文档标题和其他有用的元数据编入索引作为建议。稍后,您可以包括由于用户最终点击或购买返回的结果而被视为成功的用户输入的历史搜索。