使用Elasticsearch的Suggester实现搜索提示

根据 官方文档 创建Elasticsearch的运行环境,之后 安装中文分词插件 。启动Elasticsearch进程后根据如下的配置创建索引 products

{
    "settings": {
        "index": {
            "number_of_shards": 1,
            "number_of_replicas": 0
        }
    },
    "mappings": {
        "dynamic_templates": [
            {
                "strings": {
                    "match_mapping_type": "string",
                    "mapping": {
                        "type": "keyword",
                        "fields": {
                            "analyzed": {
                                "type": "text",
                                "analyzer": "ik_max_word"
                            }
                        }
                    }
                }
            }
        ],
        "properties": {
            "suggest": {
                "type": "completion"
            }
        }
    }
}

在上面的mapping中我们把 suggest 字段设置成了 completion 类型,该类型支持 completion_suggest 的搜索。

索引数据

在创建了索引之后,我们向索引中写入的数据格式如下

{
    "updateTime": "2016-09-01T10:59:22+0800",
    "proxy": false,
    "addTime": "2016-09-01T10:59:22+0800",
    "name": "PCMS星巴克随手杯"
}

完整的数据在 这里

我们使用 python-pinyin 库把 name 字段转化为相应的拼音,例如 咖啡龙角散 被转为

[
    "kflls",
    "kafeilongjuesan",
    "kflgs",
    "kafeilonglusan",
    "kafeilonggusan",
    "kafeilongjiaosan",
    "kfljs"
]

我们在原始数据中新增一个 suggest 字段用于存储上面的拼音数据,之后把这个文档保存到 products 索引中。具体的逻辑如下

name = data.get('name')
# 将名称转化为拼音列表
suggest_values = word_2_pinyin(name)
data['suggest'] = suggest_values + [name]
requests.post(url + '/_doc', json=data)

搜索数据

我们使用 completion_suggest 对数据进行检索

requests.post(url + '/_search', json={
    'suggest': {
        'completion_suggest': {
            'prefix': word,
            'completion': {
                'field': 'suggest',
                'size': 10
            }
        }
    }
})

我们设置word为 ka 或者 kf 都可以获取到 咖啡龙角散 这个字段,如此一来便可以实现用户搜索时的提示功能了。用户输入 kafeil、kafeilong、kfl、咖啡龙 等等都可以获取到提示词“咖啡龙角散”。考虑到用户输入时参数会频繁的变化,所以completion_suggester针对速度进行了额外的优化,特别适合用于搜索提示的场景。

完整的搜索提示代码 在此

其它的suggester

除了completion_suggester,ES还提供了 Term Suggester 和 Phrase Suggester。和completion_suggester的前缀搜索不一样,它们使用了 莱文斯坦距离 来计算词之间的相关性(ES中类似的还有Fuzzy搜索),它们一般可以用于提示词纠错或拼写检查。不过因为中文的词和英文的词它们的构成原理完全不一样,而且ES中莱文斯坦距离的 max_edits 选项的值最大不能超过2,所以这几个搜索选项在中文环境中的使用场景十分有限。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章