美文网首页
二十、Elastics Search使用term filter来

二十、Elastics Search使用term filter来

作者: 书写只为分享 | 来源:发表于2019-11-27 00:54 被阅读0次

1、term filters搜索

(1)插入一些测试帖子数据

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" }

查看Mapping
GET /forum/_mapping/article

{
  "forum": {
    "mappings": {
      "article": {
        "properties": {
          "articleID": {
            "type": "keyword"
          },
          "hidden": {
            "type": "boolean"
          },
          "postDate": {
            "type": "date"
          },
          "userID": {
            "type": "long"
          }
        }
      }
    }
  }
}

现在es 5.2版本,type=text,默认会设置两个field,一个是field本身,比如articleID,就是分词的;还有一个的话,就是field.keyword,articleID.keyword,默认不分词,会最多保留256个字符

(2)根据用户ID搜索帖子

GET /forum/article/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"userID" : 1
}
}
}
}
}
term filter/query:对搜索文本不分词,直接拿去倒排索引中匹配,你输入的是什么,就去匹配什么

(3)根据帖子ID搜索帖子

GET /forum/article/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"articleID" : "XHDK-A-1293-#fJ3"
}
}
}
}
}
查不到数据,因为默认是analyzed的text类型的field,建立倒排索引的时候,就会对所有的articleID分词,分词以后,原本的articleID就没有了,只有分词后的各个word存在于倒排索引中。
(4)重建索引或者使用内至的keyword

DELETE /forum

PUT /forum
{
"mappings": {
"article": {
"properties": {
"articleID": {
"type": "keyword"
}
}
}
}
}

GET /forum/article/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"articleID.keyword" : "XHDK-A-1293-#fJ3"
}
}
}
}
}
(5)梳理学到的知识点
(1)term filter:根据exact value进行搜索,数字、boolean、date天然支持
(2)text需要建索引时指定为not_analyzed,才能用term query
2、filter执行原理深度剖析(bitset机制与caching机制)

(1)在倒排索引中查找搜索串,获取document list

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,[0, 0, 0, 1, 0, 1]

非常重要

使用找到的doc list,构建一个bitset,就是一个二进制的数组,数组每个元素都是0或1,用来标识一个doc对一个filter条件是否匹配,如果匹配就是1,不匹配就是0

[0, 1, 1]

doc1:不匹配这个filter的
doc2和do3:是匹配这个filter的

(3)遍历每个过滤条件对应的bitset,优先从最稀疏的开始搜索,查找满足所有条件的document

后面会讲解,一次性其实可以在一个search请求中,发出多个filter条件,每个filter条件都会对应一个bitset,遍历每个filter条件对应的bitset,先从最稀疏的开始遍历,就可以先过滤掉尽可能多的数据

[0, 0, 0, 1, 0, 0]:比较稀疏
[0, 1, 0, 1, 0, 1]
请求: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了

(4)caching bitset,跟踪query,在最近256个query中超过一定次数的过滤条件,缓存其bitset。对于小segment(<1000,或<3%),不缓存bitset。

segment数据量很小,此时哪怕是扫描也很快;segment会在后台自动合并,小segment很快就会跟其他小segment合并成大segment,此时就缓存也没有什么意义,segment很快就消失了

比如postDate=2017-01-01,[0, 0, 1, 1, 0, 0],可以缓存在内存中,这样下次如果再有这个条件过来的时候,就不用重新扫描倒排索引,反复生成bitset,可以大幅度提升性能。

在最近的256个filter中,有某个filter超过了一定的次数,次数不固定,就会自动缓存这个filter对应的bitset

filter比query的好处就在于会caching,但是之前不知道caching的是什么东西,实际上并不是一个filter返回的完整的doc list数据结果。而是filter bitset缓存起来。下次不用扫描倒排索引了。

(5)filter大部分情况下来说,在query之前执行,先尽量过滤掉尽可能多的数据

query:是会计算doc对搜索条件的relevance score,还会根据这个score去排序
filter:只是简单过滤出想要的数据,不计算relevance score,也不排序

(6)如果document有新增或修改,那么cached bitset会被自动更新

(7)以后只要是有相同的filter条件的,会直接来使用这个过滤条件对应的cached bitset

3、基于bool组合多个filter条件来搜索数据
(1)搜索发帖日期为2017-01-01,或者帖子ID为XHDK-A-1293-#fJ3的帖子,同时要求帖子的发帖日期绝对不为2017-01-02
GET /forum/article/_search

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,必须匹配,可以匹配其中任意一个即可,必须不匹配
(2)搜索帖子ID为XHDK-A-1293-#fJ3,或者是帖子ID为JODL-X-1937-#pV7而且发帖日期为2017-01-01的帖子
GET /forum/article/_search

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"
                    }
                  }
                  ]
              }
            }
            
            
            ]
        }
      }
    }
  }
}

相关文章

网友评论

      本文标题:二十、Elastics Search使用term filter来

      本文链接:https://www.haomeiwen.com/subject/wfeuwctx.html