文章内容中的自动完成建议

Sil*_*sen 5 search autocomplete elasticsearch

我们的目标
我们希望让我们的用户能够在他们开始输入时获得搜索建议,但 ElasticSearch 建议器没有提供任何似乎适合我们从文章中获取文本片段建议的用例。Ngramming 和搜索文档标题适用于标题很多且变化很大的索引,但对于少量文章,标题不能代表足够的信息,并且很多搜索短语返回零结果。我们也不能让用户用相关的建议线索标记所有文档。

我们的文档通常由标题和描述(正文)以及各种其他属性(如组、类别和部门)组成。

我们目前的解决方案:单独索引中的 shingles
每次我们索引文档时,我们都会调用elasticsearch _analyze端点来生成文档描述 + 标题的shingles (2-5)。然后将每个结果(带状疱疹产生大量结果)作为名为Suggestion的字段存储在新索引中原始文档的副本中。这是因为某些用户可能希望缩小对属于某个类别的文档的建议范围或我们提供的任何其他任意过滤选项。

原始文件(主索引):

{
    "Title": "A fabulous document",
    "Description": "A document with fabulous content"
    "Category": "A"
}
Run Code Online (Sandbox Code Playgroud)

建议文件(Suggestion index)

(Suggestion 1)
{
    "Title": "A fabulous document",
    "Description": "A document with fabulous content",
    "Category": "A"
    "Suggestion": "A"

}
(Suggestion 2)
{
    "Title": "A fabulous document",
    "Description": "A document with fabulous content",
    "Category": "A"
    "Suggestion": "A document"

}
...
(Suggestion N)
{
    "Title": "A fabulous document",
    "Description": "A document with fabulous content",
    "Category": "A"
    "Suggestion": "a document with"

}
Run Code Online (Sandbox Code Playgroud)

但是正如您所看到的,对于 1000 字的文章,我们很容易得到成百上千个带状疱疹,每个带状疱疹都复制了整个主文档。

为了搜索,我们在建议文档和术语聚合中进行前缀搜索以获取最常出现的单词组合,我们的用户实际上有点喜欢这个解决方案,只要他们没有更好的东西。


另一个更简单但太慢的解决方案
我们尝试使用带状疱疹分析器分析copy_to字段(自动完成),然后使用正则表达式包含过滤器进行术语聚合,以删除不以搜索短语开头的术语,但这实在是太慢了,而且很耗内存,因为每个字段的不相关术语(对于特定查询)的数量太多了。

搜索: "fabulo"

{
  "size": 0,
  "aggs": {
    "autocomplete": {
      "terms": {
        "field": "autocomplete",
        "include": {
          "pattern": "fabulo(.*)"
        }
      }
    }
  },
  "query": {
    "prefix": {
      "autocomplete": {
        "value": "fabulo"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

基于先前搜索的建议
我们正在致力于基于先前搜索短语的建议,但如果新用户的用户生成搜索很少,则他们也需要一些基于内容的自动完成建议。

问题:
有什么办法可以更快、更简单、更好地做到这一点?ElasticSearch建议器似乎都要求您提前了解建议或具有描述性标题。似乎非常适合产品建议,但不适用于大型文本内容建议。另外,我们还需要考虑过滤问题。

dsm*_*mog 0

我们使用带状疱疹和聚合的组合形成专用索引:

  1. 选择所有应该作为自动完成短语来源的字段,并添加带有带状疱疹过滤器的子字段
"type": "shingle",
            "max_shingle_size": 3,
            "min_shigle_size": 1
          },
Run Code Online (Sandbox Code Playgroud)
  1. 定期查询所有这些字段上的术语聚合索引,从所有聚合中收集关键字,对所有聚合中每个关键字(或短语,如果是 2、3 个字带状疱疹)的文档计数求和
  2. 将结果关键字放在单独的索引中,以提取的文档数作为权重
  3. Elastic 现在支持上下文字段来缩小建议索引范围,请参阅https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters.html#context-suggester
  4. 将自动完成搜索定向到单独的索引