首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…
一. 前言
本来是想在学习倒排索引的时候把这一块捋一下的,没想到看到后面发现这一块东西还是蛮多的,所以准备了解一下。
整体概念了解得有点迷迷糊糊,后续有机会还是得瞅一瞅具体得源码实现方式。
二. FST 长什么样
常规路径图
如果我有 abc ,ebc ,obc ,acc ,abe ,ebe 这几个单词,那么对应的 FST 是这样的 :
但看这张图几个主要的特点:
- 将完整的单词拆成一个个单元
- 第二个关注点就是相同的前缀和后缀都会复用
- 第三方特点是有始有终,不会中途插入
发生折返现象
如果我有 abcde ,cde ,acde 三个参数 :
这里可以看到,abcde 和 cde 其实使用的是同一个序列。
阶段总结 : 从形成的这两个图里面大概看出来 FST 是一个什么样的东西,那么后面来学习他的官方概念。
三. FST 的概念
FST 全名 : (Finite State Transducer)有限状态自动机,是一种基于有限状态机的数据结构。
FST 是一个有向图 ,每个节点表示一个状态,每个节点(状态)可以有多个出边 ,每个出边都有对应的标签和权重。
在 FST 中,从根节点到任何其他节点的路径都代表一个键,并且权重表示该键的相关度或分值。
常见场景 :
- 自动补全 ,拼写检查和查询建议 ,语音识别、文本转换和关键字提取
- 关键字的威胁检测系统,快速匹配恶意代码和网络攻击等
- DNA序列比对和匹配
3.1 常见场景解析
// 自动补全
- 自动补全功能应该是最贴切的,将输入的字符串作为前缀进行匹配,并从有限状态机的根节点开始查找,找到对应匹配的状态
- 然后,FST 将从匹配状态开始的所有可达状态作为候选词返回,以便用于自动补全
3.2 FST 在ES中的使用
ES 中 FST 主要用于实现自动补全和建议搜索功能。将搜索词转换成状态转换序列,然后在 FST 中查找匹配的状态转换序列,最终得到匹配的建议词或者完成自动补全。
Elasticsearch 还可以通过自定义 FST 来实现特定的分词器和词库,在不同的场景中加快了查询的速度,提高效率。
全部流程
// S1 : 构建 FST 结构
当数据开始逐渐生成后,通过分词器按照不同的方式进行分词,在把所有的词项构建成 FST
// S2 : 查询的转换
当用户进行查询时,会将查询词按照分词器的逻辑进行分词,然后按照分词结果转换为查询状态序列
// S3 : 查找匹配的状态转换序列
使用深度优先搜索或广度优先搜索算法在有限状态自动机中查询匹配的状态序列,匹配上则可以找到一个对应的词项
// S4 : 通过词项获取
在 FST 中找到了一个匹配的词项,就可以返回该词项的相关信息,比如文档 ID、权重等
关键概念 :词项和倒排索引的辅助关系
- 倒排索引 :用于将每个词与包含该词的文档相关联,每个文档里面的相关词项都会作为关键词,再把这些关键词和对应的文档进行映射关联
- FST 词项 : 用于将查询词进行分词,词干提取,通过 FST 快速进行搜索
实现方式
ES 分析器:也就是上文提到的分词器,这里直接引用官方的解释 :
@ 分析与分析器 | Elasticsearch: 权威指南 | Elastic
// 过程 :
- 首先,将一块文本分成适合于倒排索引的独立的词条 ,
- 之后,将这些词条统一化为标准格式以提高它们的“可搜索性”,或者 recall
// 功能点 : 分析器实际上包含三个功能
S1 : 字符过滤器,在分词前整理字符串,例如去掉 HTML , 特殊符号等等
S2 : 分词器,字符串被 *分词器* 分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条
S3 : Token 过滤器中对词条进行改造,可能会改变,增加,删除 (过滤停用词、转换大小写、同义词替换)
// 常见的分析器 :
标准分析器 :删除绝大部分标点 ,词条小写等等
简单分析器 :在任何不是字母的地方分隔文本
空格分析器 :在空格的地方划分文本
语言分析器 :考虑指定语言的特点
// FST 的处理流程 :
FST 通常用于存储和查询建议词,以便支持自动补全功能。
当用户输入一个前缀字符串时,Analyzer 会使用 Tokenizer 将这个字符串分割成若干个单词,并将这些单词传递给 FST 进行前缀匹配,从而返回与前缀匹配的建议词列表
四. FST 疑问解答
4.1 FST 如何提高效率
单纯就从 FST 的查询方式看都能看出其查询的效率,同时 FST 还有一些其他的好处 :
- 数据压缩 :FST 的特性决定了他的数据结构是紧凑的,按照之前看到的一篇文章的数据 :10TB 磁盘数据量,其对应的 FST 内存占用量在 10GB ~ 15GB 左右
- 可定制规则 : FST 的分词和自动化处理的算法都是可以定制和精简的,可以根据情况和优化对处理效率进行提高
- 可用复杂的算法 :深度优先搜索、广度优先搜索、剪枝等都可用提高了处理速度
- 并行处理 :可以通过并行计算和分布式处理等技术,将大规模的数据处理分成多个任务,提高处理效率和并发性
4.2 FST 怎么对结尾复用
前面看到了,FST 的数据结构导致其可能存在重复的状态,那么 FST 是如何处理重复状态的呢?
这一块大概了解了一下,不能保证一定是对的~~~
常见的有2种方式 :
在状态中保存多个输出字符串
简单点说,就是在一个结尾状态中存在多个输出匹配项。 通常我们一条路走到这个结尾时,都是一个单词。而存在结尾相同的情况下,这个尾节点中就会存在多个输出单词。
例如 : 123ab 和 456ab ,在尾部的 b 节点中,会存在 123ab 和 456ab 两个匹配项。再根据具体的需求返回输出项对应的信息。
添加结尾标识
这种对应的应该是 123ab 和 456abc ,当到了 a-b 状态时,b 后面会有 c 状态和一个结尾状态,通过结尾状态就可以匹配对应的词项
怎么说呢,还是有点不透彻,没太理解这个结构,可能是翻译的误差,有懂得可以在评论聊一聊
总结
功能点不大,业务场景本身也没看过具体得实现方式,先了解一下~~