本套技术专栏作者(秦凯新)专注于大数据及容器云核心技术解密,具备5年工业级IOT大数据云平台建设经验,可提供全栈的大数据+云原生平台咨询方案,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。详情请关注《数据云技术社区》公众号。
1 如何倒排索引
date来举例
word doc1 doc2 doc3
2017-01-01 * *
2017-02-02 * *
2017-03-03 * * *
filter:2017-02-02
到倒排索引中一找,发现2017-02-02对应的document list是doc2,doc3
2 构建一个bitset
- 使用找到的doc list,构建一个bitset,就是一个二进制的数组,数组每个元素都是0或1,用来标识一个doc对一个filter条件是否匹配,如果匹配就是1,不匹配就是0
[0, 1, 1] doc1:不匹配这个filter的 doc2和do3:是匹配这个filter的 尽可能用简单的数据结构去实现复杂的功能,可以节省内存空间,提升性能 - 遍历每个过滤条件对应的bitset,优先从最稀疏的开始搜索,查找满足所有条件的document,一次性其实可以在一个search请求中,发出多个filter条件,每个filter条件都会对应一个bitset,遍历每个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 就可以将document作为结果返回给client了
3 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。
- segment数据量很小,此时哪怕是扫描也很快;segment会在后台自动合并,小segment很快就会跟其他小segment合并成大segment,此时就缓存也没有什么意义,因为segment很快就消失了。
- filter比query的好处就在于会caching,但是之前不知道caching的是什么东西,实际上并不是一个filter返回的完整的doc list数据结果。而是filter bitset缓存起来。下次不用扫描倒排索引了。
- filter大部分情况下来说,在query之前执行,先尽量过滤掉尽可能多的数据,query:是会计算doc对搜索条件的relevance score,还会根据这个score去排序,filter:只是简单过滤出想要的数据,不计算relevance score,也不排序
4 Caching bitset自动更新机制
- Caching 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]
- 以后只要是有相同的filter条件的,会直接来使用这个过滤条件对应的cached bitset
5 联合过滤案例
- 搜索发帖日期为2017-01-01,或者帖子ID为XHDK-A-1293-#fJ3的帖子,同时要求帖子的发帖日期绝对不为2017-01-02
select *
from forum.article
where (post_date='2017-01-01' or article_id='XHDK-A-1293-#fJ3')
and post_date!='2017-01-02'
POST /forum/article/_bulk
{ "index": { "_id": 1 }}
{ "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 2 }}
{ "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" }
{ "index": { "_id": 3 }}
{ "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" }
{ "index": { "_id": 4 }}
{ "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }
GET /forum/article/_search
{
"query": {
"constant_score": {
"filter": {
"bool": {
"should": [
{"term": { "postDate": "2017-01-01" }},
{"term": {"articleID": "XHDK-A-1293-#fJ3"}}
],
"must_not": {
"term": {
"postDate": "2017-01-02"
}
}
}
}
}
}
}
must,should,must_not,filter:必须匹配,可以匹配其中任意一个即可,必须不匹配
- 搜索帖子ID为XHDK-A-1293-#fJ3,或者是帖子ID为JODL-X-1937-#pV7而且发帖日期为2017-01-01的帖子
select *
from forum.article
where article_id='XHDK-A-1293-#fJ3'
or (article_id='JODL-X-1937-#pV7' and post_date='2017-01-01')
GET /forum/article/_search
{
"query": {
"constant_score": {
"filter": {
"bool": {
"should": [
{
"term": {
"articleID": "XHDK-A-1293-#fJ3"
}
},
{
"bool": {
"must": [
{
"term":{
"articleID": "JODL-X-1937-#pV7"
}
},
{
"term": {
"postDate": "2017-01-01"
}
}
]
}
}
]
}
}
}
}
}
6 总结
本套技术专栏作者(秦凯新)专注于大数据及容器云核心技术解密,具备5年工业级IOT大数据云平台建设经验,可提供全栈的大数据+云原生平台咨询方案,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,如有任何学术交流,可随时联系。详情请关注《数据云技术社区》公众号。