转自:http://www.cnblogs.com/LBSer/p/4119841.html

1 lucene字典

使用lucene进行查询不可避免都会使用到其提供的字典功能,即根据给定的term找到该term所对应的倒排文档id列表等信息。实际上lucene索引文件后缀名为tim和tip的文件实现的就是lucene的字典功能。

怎么实现一个字典呢?我们马上想到排序数组,即term字典是一个已经按字母顺序排序好的数组,数组每一项存放着term和对应的倒排文档id列表。每次载入索引的时候只要将term数组载入内存,通过二分查找即可。这种方法查询时间复杂度为Log(N),N指的是term数目,占用的空间大小是O(N*str(term))。排序数组的缺点是消耗内存,即需要完整存储每一个term,当term数目多达上千万时,占用的内存将不可接受。

2 常用字典数据结构

很多数据结构均能完成字典功能,总结如下。

数据结构 优缺点
排序列表Array/List 使用二分法查找,不平衡
HashMap/TreeMap 性能高,内存消耗大,几乎是原始数据的三倍
Skip List 跳跃表,可快速查找词语,在lucene、redis、Hbase等均有实现。相对于TreeMap等结构,特别适合高并发场景(Skip List介绍)
Trie 适合英文词典,如果系统中存在大量字符串且这些字符串基本没有公共前缀,则相应的trie树将非常消耗内存(数据结构之trie树)
Double Array Trie 适合做中文词典,内存占用小,很多分词工具均采用此种算法(深入双数组Trie)
Ternary Search Tree 三叉树,每一个node有3个节点,兼具省空间和查询快的优点(Ternary Search Tree)
Finite State Transducers (FST) 一种有限状态转移机,Lucene 4有开源实现,并大量使用

3 FST原理简析

lucene从4开始大量使用的数据结构是FST(Finite State Transducer)。FST有两个优点:1)空间占用小。通过对词典中单词前缀和后缀的重复利用,压缩了存储空间;2)查询速度快。O(len(str))的查询时间复杂度。

下面简单描述下FST的构造过程(工具演示:http://examples.mikemccandless.com/fst.py?terms=&cmd=Build+it%21)。我们对“cat”、 “deep”、 “do”、 “dog” 、“dogs”这5个单词进行插入构建FST(注:必须已排序)。

1)插入“cat”

插入cat,每个字母形成一条边,其中t边指向终点。

2)插入“deep”

与前一个单词“cat”进行最大前缀匹配,发现没有匹配则直接插入,P边指向终点。

3)插入“do”

与前一个单词“deep”进行最大前缀匹配,发现是d,则在d边后增加新边o,o边指向终点。

4)插入“dog”

与前一个单词“do”进行最大前缀匹配,发现是do,则在o边后增加新边g,g边指向终点。

5)插入“dogs”

与前一个单词“dog”进行最大前缀匹配,发现是dog,则在g后增加新边s,s边指向终点。

最终我们得到了如上一个有向无环图。利用该结构可以很方便的进行查询,如给定一个term “dog”,我们可以通过上述结构很方便的查询存不存在,甚至我们在构建过程中可以将单词与某一数字、单词进行关联,从而实现key-value的映射。

4 FST使用与性能评测

我们可以将FST当做Key-Value数据结构来进行使用,特别在对内存开销要求少的应用场景。Lucene已经为我们提供了开源的FST工具,下面的代码是使用说明。

 1 public static void main(String[] args) {2         try {3             String inputValues[] = {"cat", "deep", "do", "dog", "dogs"};4             long outputValues[] = {5, 7, 17, 18, 21};5             PositiveIntOutputs outputs = PositiveIntOutputs.getSingleton(true);6             Builder<Long> builder = new Builder<Long>(FST.INPUT_TYPE.BYTE1, outputs);7             BytesRef scratchBytes = new BytesRef();8             IntsRef scratchInts = new IntsRef();9             for (int i = 0; i < inputValues.length; i++) {
10                 scratchBytes.copyChars(inputValues[i]);
11                 builder.add(Util.toIntsRef(scratchBytes, scratchInts), outputValues[i]);
12             }
13             FST<Long> fst = builder.finish();
14             Long value = Util.get(fst, new BytesRef("dog"));
15             System.out.println(value); // 18
16         } catch (Exception e) {
17             ;
18         }
19     }

FST压缩率一般在3倍~20倍之间,相对于TreeMap/HashMap的膨胀3倍,内存节省就有9倍到60倍!(摘自:把自动机用作 Key-Value 存储),那FST在性能方面真的能满足要求吗?

下面是我在苹果笔记本(i7处理器)进行的简单测试,性能虽不如TreeMap和HashMap,但也算良好,能够满足大部分应用的需求。

参考文献

http://sbp810050504.blog.51cto.com/2799422/1361551

http://blog.sina.com.cn/s/blog_4bec92980101hvdd.html

http://blog.mikemccandless.com/2013/06/build-your-own-finite-state-transducer.html

http://examples.mikemccandless.com/fst.py?terms=mop%2F0%0D%0Amoth%2F1%0D%0Apop%2F2%0D%0Astar%2F3%0D%0Astop%2F4%0D%0Atop%2F5%0D%0Atqqq%2F6&cmd=Build+it%21

转载于:https://www.cnblogs.com/bonelee/p/6226185.html

lucene字典实现原理——FST相关推荐

  1. lucene字典实现原理

    文章转自https://www.cnblogs.com/LBSer/p/4119841.html 1 lucene字典 使用lucene进行查询不可避免都会使用到其提供的字典功能,即根据给定的term ...

  2. Lucene 倒排索fst引原理与实现

    整理下几篇博客 1 Lucene 4.X 倒排索引原理与实现: (3) Term Dictionary和Index文件 (FST详细解析) https://www.cnblogs.com/forfut ...

  3. python字典实现原理-哈希函数-解决哈希冲突方法

    python字典实现原理-哈希函数-解决哈希冲突方法 参考文章: (1)python字典实现原理-哈希函数-解决哈希冲突方法 (2)https://www.cnblogs.com/guyannanfe ...

  4. Lucene 7.5.0 FST算法

    FST(Finite State Transducer)算法的概念在这篇博客中并不涉及,网上有太多的资料啦,写的都非常的不错.这里推荐这位网友的介绍:https://www.shenyanchao.c ...

  5. (转)字典树原理+实现

    字典树,高端点就是tire树,或者前缀树,其实就是一个挺简单的算法,但一直没学,昨晚上训练有涉及到,今天来突击一下,发现不是那么难 先插眼一个大牛的博客(因为实在懒得复制粘贴了): https://b ...

  6. 带你自学Python系列(九):一文读懂Python中字典应用原理!

    ↑ 点击上方[计算机视觉联盟]关注我们 今天是小编持续更新关于Python的知识总结以及Python实践项目应用的第9天,带你利用零碎时间自学最受欢迎的编程语言之一Python语言.你和小编一起打卡了 ...

  7. python字典实现原理_python学习笔记_第7天(字典底层原理+选择结构)

    字典:(拓展–重要)字典核心底层原理 字典对象的核心是散列表,散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做bucket. 每个bucket 有两部分:一个是键对象的引用,一个是值对 ...

  8. 字典树原理详解及其Python实现

    一.原理详解 1.初步介绍: 字典树又名前缀树,Trie树,是一种存储大量字符串的树形数据结构,经常被搜索引擎系统用于文本词频统计. 除此之外也常用于计算左右信息熵.计算点互信息. 下图演示了一个保存 ...

  9. Lucene中倒排索引原理

    1.简介 倒排索引源于实际应用中需要根据属性的值来查找记录.这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址.由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引 ...

最新文章

  1. android 固定底部,如何将view固定在屏幕底部?
  2. java swing图形界面开发与案例详解source code
  3. Swift游戏开发实战教程(大学霸内部资料)
  4. Python操作ElasticSearch
  5. 10个奇幻的HTML5和Javascript效果
  6. kafka 数据可靠性深度解读
  7. Elasticsearch——利用Parent-Child关系解决大数据场景下的实时查询
  8. 视频问答PPT大放送丨中信银行邓琼-GoldenDB分布式数据库研发与应用实践
  9. 12GB超大内存!华为超级旗舰手机悄悄现身
  10. ansys怎么建立弯曲圆柱_ANSYS复合材料分析
  11. 视觉SLAM——ORB-SLAM2运行tum数据集,kitti数据集,euroc数据集
  12. 「leetcode」452. 用最少数量的箭引爆气球【贪心算法】详细图解
  13. 20.HTTP-NG
  14. 用excel来做项目管理?
  15. 计算机组成原理(白中英) 第六章 课后题答案
  16. 第7章非线性系统的分析-7.1非线性系统的基本概念
  17. linux之svn回滚/回退到某个版本
  18. C语言学习-翁凯(第十三章笔记)
  19. 记录delphi 海康摄像机登陆
  20. 一个视频分割为多个视频片段

热门文章

  1. c语言数据结构线性表LA和LB,数据结构(C语言版)设有线性表LA(3,5,8,110)和LB(2,6,8,9,11,15,20)求新集合?...
  2. matlab温度数据怎么滤波_卡尔曼滤波算法思想理解 Kalman filter 第一篇
  3. mysql8自定义安装位置_【MySQL】Windows10:MySQL 8 自定义路径安装
  4. 循环数组函数c语言,C语言练习题2(分支结构循环结构数组函数2009-2012二级真题)..doc...
  5. 轴只显示5个刻度_组团投资5亿元!武平集中签约5个新型显示产业链投资项目
  6. vb.net 正则 替换 第n个_Python中正则表达式模块详解
  7. mysql数据放在什么位置,mysql数据存放的位置在哪
  8. linux 0.11根文件系统,linux内核与根文件系统之间的关联的理解
  9. java for index_Java增强for循环中获取index
  10. mysql一些原生基本操作