如何添加" context"到弹性搜索建议

时间:2018-05-15 14:36:31

标签: elasticsearch

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

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

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

目前的映射是:

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将根据标题中字母的一致性来搜索标题,而不是标题之间的相关性。

例如,如果我的用户是' 理发师',ElasticSearch可能会建议' bartender ',因为他们有一个共同点: b,a,r,e,r

因此,我有两个问题:

1 - 我的假设是正确的吗?

2 - 如何在我的图书搜索中添加更多相关性?

1 个答案:

答案 0 :(得分:0)

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

bartender的示例类似于babarbart等。 正如您所看到的,对于barber,您将有一些类似的n-gram,这将是匹配。

关于您的问题,如果您降低minimum_should_match,您将获得更多结果,但这仅仅是因为以下匹配程序将导致部分匹配。

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

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