搜索引擎关键字智能提示实践

本文介绍了搜索引擎关键字智能提示的实现,主要通过Trie树进行前缀匹配查询,并结合模型排序来提升用户体验。首先,文章详细阐述了Trie树的概念、插入、查询和删除过程。接着,介绍了雪球的搜索提示系统,包括系统架构、Trie树的维护和召回策略,以及模型排序的逻辑回归算法。最后,文章总结了Trie树在提高搜索性能和准确性方面的作用,并展望了未来的优化方向。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为了提高阅读体验,请移步到:搜索引擎关键字智能提升实践

一、背景

搜索关键字智能提示是一个搜索应用的标配,主要作用是避免用户输入错误的搜索词,并将用户引导到相应的关键词上,以提升用户使用体验。

雪球以连接人与资产,让财富的雪球越滚越大为使命,在投资社区领域处于领先地位。为了让用户快速准确找到目标的股票,大V,我们搭建搜索提示系统(以下简称Sug系统)来自动补全 Query。用户在查找股票时主要输入股票名称、股票 Symbol 进行搜索,为了提升用户体验和输入效率,本文实现了一种基于 Trie 树前缀匹配查询 + 模型排序关键词智能提示(Suggestion)实现。

二、需求分析

  • 支持前缀匹配原则:在搜索框中输入 “中国”,搜索框下面会以 “中国” 为前缀,展示 “中国平安”、“中国神华”、“中国中免” 等搜索词;输入“贵州”,会提示 “贵州茅台”、“贵州燃气”、“贵州百灵”等搜索词。

  • 同时支持汉字、拼音输入:由于中文的特点,如果搜索自动提示可以支持拼音的话会给用户带来更大的方便,免得切换输入法。比如,输入 [zhongguo] 提示的关键字和输入 “中国” 提示的一样,输入 [guizhou] 与输入 “贵州” 提示的关键字一样。

  • 支持拼音缩写输入:对于较长关键字,为了提高输入效率,有必要提供拼音缩写输入。比如输入 “zg” 应该能提示出 [zhongguo] 相似的关键字,输入 [gzmt] 也一样能提示出 “贵州茅台” 关键字。

  • 支持多音字输入提示:比如输入 [chongqing] 或者 [zhongqing] 可以提示出 “重庆啤酒”、“重庆钢铁”、“重庆百货”。

  • 支持大写数字转阿拉伯数字:比如输入 [360] 可以提示出 “三六零” 这只股票。

  • 支持 Query 纠错:比如输入 “贵州毛台” 可以提示出 “贵州茅台”。

三、解决方案

什么是 Tire 树

Tire 树,也叫字典树,又称单词查找树或键树,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

Trie 树的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

它有3个基本性质:

  1. 根节点不包含字符,除根节点外,每一个节点都只包含一个字符。

  1. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。

  1. 每个节点的所有子节点包含的字符都不相同。

Trie Tree 是一颗存储多个字符串的树,树的每条分支代表一个字符串。和普通树不同的地方是,相同的字符串前缀共享同一条分支。例如给出一组字符串:中国平安、中国银行、中兴通讯、中信证券、平安银行、平安、zgpn 等。我们可以构建出下面的 Trie 树:

其中,绿色节点是数据节点,黄色节点是普通节点。从根节点到绿色节点的一条路径表示一个字符串(注意:数据节点并不都是叶子节点)。

由上图可知,当用户输入 “中国” 的时候,搜索框会展示以 “中国” 为前缀的 “中国平安”、“中国银行”等关键词;当用户输入 “中兴” 的时候,搜索框里面会提示以 “中兴” 为前缀的“中兴通讯”等关键词。

Trie 树的实现

插入过程

为了更容易理解 Trie 树是怎么构造出来的,我画了一个 Trie 树构造的分解过程。构造过程的每一步,都相当于往 Trie 树中插入一个字符串。当所有字符串都插入完成之后,Trie 树就构造好了。

以下代码是 Trie 树插入的 demo


class TrieNode:    def __init__(self, char=None):        self.char = char        self.data = None        self.children = {}    def is_data_node(self):        return self.data is not None    def is_leaf_node(self):        return len(self.children) == 0class Trie:    def __init__(self):        self.root = TrieNode("/")    def insert(self, text):        if not text: return        p = self.root        for char in text:            if char not in p.children:                p.children[char] = TrieNode(char)            p = p.children[char]        p.data = text

查询过程

精确查询

在 Trie 树中查询 “中国平安”时,需要将字符串分割成单个字符:中、国、平、安,然后从 Trie 树的根节点开始匹配。如图所示,红色路径就是在 Trie 树中的匹配路径。

以下代码是 Trie 树精确查询的 demo


    def find_node(self, pattern):        if not pattern: return        p = self.root        for char in pattern:            if char not in p.children: return            p = p.children[char]        return p
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值