二十四 Elasticsearch
1 Elasticsearch 的倒排索引
传统的检索方式是通过文章,逐个遍历找到对应关键词的位置。 倒排索引,是通过分词策略,形成了词和文章的映射关系表,也称倒排表,这种词典 + 映射表即为倒排索引。
其中词典中存储词元,倒排表中存储该词元在哪些文中出现的位置。 有了倒排索引,就能实现 O(1) 时间复杂度的效率检索文章了,极大的提高了检索效率。
倒排索引的底层实现是基于:FST(Finite State Transducer)数据结构。Lucene 从 4+ 版本后开始大量使用的数据结构是 FST。FST 有两个优点: 1)空间占用小。通过对词典中单词前缀和后缀的重复利用,压缩了存储空间; 2)查询速度快。O(len(str)) 的查询时间复杂度。
2 字典树介绍
Elasticsearch中的字典树(Trie Tree)或称为前缀树(Prefix Tree)是一种用于处理字符串数据的高效数据结构。特别是在其倒排索引的构建中,字典树发挥了重要作用。其核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。它有 3 个基本性质:
① 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
② 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
③ 每个节点的所有子节点包含的字符都不相同。或者用数组来模拟动态。而空间的花费,不会超过单词数×单词长度。
对于中文的字典树,每个节点的子节点用一个哈希表存储,这样就不用浪费太大的空间,而且查询速度上可以保留哈希的复杂度 O(1),实现:对每个结点开一个字母集大小的数组,每个结点挂一个链表,使用左儿子右兄弟表示法记录这棵树
3 Elasticsearch 索引文档过程
索引文档指文档写入 ES,创建索引的过程。
第一步:客户端向集群某节点写入数据,发送请求。(如果没有指定路由/协调节点,请求的节点扮演协调节点的角色。)
第二步:协调节点接受到请求后,默认使用文档 ID 参与计算(也支持通过routing),得到该文档属于哪个分片。随后请求会被转到另外的节点。复制
// 路由算法:根据文档 id 或路由计算目标的分片 id
shard = hash(document_id) %</