【问题标题】:Autocomplete suggestions from article content文章内容中的自动完成建议
【发布时间】:2017-08-22 13:39:13
【问题描述】:

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

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

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

原始文件(主索引):

{
    "Title": "A fabulous document",
    "Description": "A document with fabulous content"
    "Category": "A"
}

建议文件(建议索引)

(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"

}

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

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


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

搜索:“fabulo”

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

根据以前的搜索提供建议
我们正在努力根据以前的搜索词组提供建议,但如果新用户的用户生成的搜索很少,他们也需要根据内容获得一些自动完成建议。

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

【问题讨论】:

  • 你看过edge-nGrams吗?您可以在 edge-nGrams 字段上使用搜索查询,而不是使用建议 API。它不会像建议那样快,但您将能够获得不错的响应时间,IMO。
  • 我已经在使用 edgeNgrams 对标题进行自动完成建议。但是对于许多用户来说,只是没有足够的标题来提供任何好的建议,并且需要使用正文内容(数千字)。你看到 edgeNgrams 能帮上忙吗?我将如何从中提取建议短语?
  • 如果您想在每次击键时提出建议,我也会在描述字段中使用 edgeN-gram。可以使用合适的荧光笔生成片段,也许是 Postings(返回完整的句子)
  • @ArchitSaxena,这实际上是一个绝妙的主意。如果这行得通,你应该得到奖励,因为它可以让我摆脱 10 亿份文件(不是在开玩笑)!我会立即尝试:-)
  • 太好了。 :) 那么奖品是什么哈哈?

标签: search elasticsearch autocomplete


【解决方案1】:

我们将 shingles 和聚合结合到一个专用索引中:

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

【讨论】:

  • 感谢您的建议。您能否详细说明“Elastic 现在支持类别字段以缩小建议索引”?我不确定我知道您具体指的是哪个功能。
  • 啊,它被称为“上下文”而不是类别。您可以将多个此类上下文添加到每个建议记录以添加额外的过滤。请注意,Elastic 7 中的上下文数量是有限的。请参阅:elastic.co/guide/en/elasticsearch/reference/current/…
猜你喜欢
  • 2020-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
相关资源
最近更新 更多