【问题标题】:How to add "context" to Elastic Search suggestions如何向 Elastic Search 建议添加“上下文”
【发布时间】:2018-05-15 14:36:31
【问题描述】:

我正在构建一个企业社交网络。

我想建议人们根据他们的头衔添加为朋友。 例如,值可以是:开发者、博主、歌手、理发师、调酒师……

我的用户被保存到 ElasticSearch 中,他们的标题保存在“标题”字段中。

当前映射为:

title: {
    type: 'text',
    analyzer: 'autocomplete_analyzer',
    search_analyzer: 'autocomplete_analyzer_search'
}

查询是:

should: [
    {
        match: {
            title: {
                query: user.title,
                minimum_should_match: '90%',
                boost: 2
            }
        }
    }
]

分析器的定义是:

indexConfig: {
    settings: {
        analysis: {
            analyzer: {
                autocomplete_analyzer: {
                    tokenizer: 'autocomplete_tokenizer',
                    filter: ['lowercase', 'asciifolding']
                },
                autocomplete_analyzer_search: {
                    tokenizer: 'lowercase',
                    filter: ['asciifolding']
                },
                phrase_analyzer: {
                    tokenizer: 'standard',
                    filter: ['lowercase', 'asciifolding', 'fr_stop', 'fr_stemmer', 'en_stop', 'en_stemmer']
                },
                derivative_analyzer: {
                    tokenizer: 'standard',
                    filter: ['lowercase', 'asciifolding', 'derivative_filter', 'fr_stop', 'fr_stemmer', 'en_stop', 'en_stemmer']
                }
            },
            tokenizer: {
                autocomplete_tokenizer: {
                    type: 'edge_ngram',
                    min_gram: 2,
                    max_gram: 20,
                    token_chars: ['letter', 'digit']
                }
            },
            filter: {
                derivative_filter: {
                    type: 'word_delimiter',
                    generate_word_parts: true,
                    catenate_words: true,
                    catenate_numbers: true,
                    catenate_all: true,
                    split_on_case_change: true,
                    preserve_original: true,
                    split_on_numerics: true,
                    stem_english_possessive: true
                },
                en_stop: {
                    type: 'stop',
                    stopwords: '_english_'
                },
                en_stemmer: {
                    type: 'stemmer',
                    language: 'light_english'
                },
                fr_stop: {
                    type: 'stop',
                    stopwords: '_french_'
                },
                fr_stemmer: {
                    type: 'stemmer',
                    language: 'light_french'
                }
            }
        }
    }
}

我测试了,相关性很好,但是他们没有足够的用户匹配这个,因为'90%'标准

一个快速而肮脏的解决方案当然是将这个标准降低到 50%。

但是,如果我这样做,我认为 Elastic 将根据标题中字母的一致性来搜索标题,而不是标题之间接近度的相关性。

例如,如果我的用户是“barber”,ElasticSearch 可能会建议“bartender”,因为他们有共同点:b,a,r ,e,r

因此,我有两个问题:

1 - 我的假设正确吗?

2 - 我可以做些什么来增加我的标题搜索的相关性?

【问题讨论】:

  • 为什么要使用自动完成分析器?
  • 我不知道,是另一个人创建了初始映射
  • 您能否展示一下这个 autocomplete_analyzer 定义的外观,以确保它符合我的预期
  • 好的,我编辑帖子

标签: elasticsearch


【解决方案1】:

您的搜索问题如下 - 它使用 autocomplete_analyzer,它基本上创建了一个包含大量 n-gram 的 巨大 索引。

bartender 的示例类似于 babarbart 等。 如您所见,对于barber,您将有一些相似的 n-gram,这将进行匹配。

关于你的问题,如果你降低minimum_should_match你会得到更多的结果,但这只是因为下面的匹配过程会导致部分匹配。

为了增加相关性 - 我建议使用另一个分析器,因为这个 n-gram 分析器通常只适用于 autosuggest 功能,但事实并非如此。从保持简单到keyword analyzerwhitespace 可能有多种选择。

更重要的是正确构建查询。例如,如果用户搜索部分标题,例如bar,您可以使用prefix query。但是,如果您仅通过完全匹配进行搜索(例如 developerbartender),则正确规范标题字段会更重要。例如。使用带有一些词干的lowercase analyzer

【讨论】:

  • 非常感谢@Mysterion 的详细回答:)
猜你喜欢
  • 2022-06-11
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多