编程界的小学生 2017-12-27 07:50:54编程
直接举例说明数组
1.假设如今要在倒排索引中去搜索字符串(xxx)
缓存
好比以下有个倒排索引列表:数据结构
我如今要搜索:2017-02-02
post
去倒排索引中找,发现对应的document list是doc2和doc3性能
2.为每一个在倒排索引中搜索到的结果,构建一个bitsetspa
使咱们找到的doc list构建一个bitset,就是一个二进制数组,数组每一个元素都是0或1。用来标识一个doc对一个filter条件是否匹配,若是匹配就是1,不匹配就是0排序
[0,1,1]索引
doc1:不匹配这个filter的内存
doc2和doc3:匹配这个filter的
尽量用简单的数据结构去实现复杂的功能,能够节省内存空间,提高性能
3.遍历每一个过滤条件对应的bitset,优先从最稀疏的开始搜索,查找知足全部条件的document
一次性其实能够在一个search请求中,发出多个filter条件,每一个filter条件都会对应一个bitsite,遍历每一个filter条件对应的bitset,先从最稀疏的开始遍历
[0, 0, 0, 1, 0, 0]:比较稀疏
[0, 1, 0, 1, 0, 1]
先遍历比较稀疏的bitset,就能够先过滤掉尽量多的数据
遍历全部的bitset,找到匹配全部filter条件的doc
请求:filter,postDate=2017-01-01,userID=1
postDate: [0, 0, 1, 1, 0, 0]
userID: [0, 1, 0, 1, 0, 1]
遍历完两个bitset以后,找到的匹配全部条件的doc。就是doc4,就能够将doc4做为结果返回给client了
4.caching bitset
跟踪query,在最近256个query中超过必定次数的过滤条件,缓存其bitset。对于小segment(<1000,或<3%),不缓存bitset。
好比postDate=2017-01-01, [0,0,1,1,0,0],能够缓存在内存中,这样下次若是再有这个条件过来的时候,就不用从新扫描倒排索引,不用反复生成bitset,能够大幅度提高性能。
在最近的256个filter中,有某个filter超过了必定的次数,次数不固定,就会自动缓存这个filter对应的bitset
lter针对小segment获取到的结果,能够不缓存,segment记录数<1000,或者segment大小<index总大小的3%
segment数据量很小,此时哪怕是扫描也很快;segment会在后台自动合并,小segment很快就会跟其余小segment合并成大segment,此时就缓存也没有什么意义,segment很快就消失了
针对一个小segment的bitset,[0, 0, 1, 0]
filter比query的好处就在于会caching,可是以前不知道caching的是什么东西,实际上并非一个filter返回的完整的doc list数据结果。而是filter bitset缓存起来。下次不用扫描倒排索引了。
5. filter大部分状况下来讲,在query以前执行,先尽可能过滤掉尽量多的数据
query:是会计算doc对搜索条件的relevance score,还会根据这个score去排序
filter:只是简单过滤出想要的数据,不计算relevance score,也不排序
6. 若是document有新增或修改,那么cached bitset会被自动更新
postDate=2017-01-01,[0, 0, 1, 0]
document,id=5,postDate=2017-01-01,会自动更新到postDate=2017-01-01这个filter的bitset中,全自动,缓存会自动更新。postDate=2017-01-01的bitset,[0, 0, 1, 0, 1]
document,id=1,postDate=2016-12-30,修改成postDate-2017-01-01,此时也会自动更新bitset,[1, 0, 1, 0, 1]
7. 之后只要是有相同的filter条件的,会直接来使用这个过滤条件对应的cached bitset