二十、Elastics Search使用term filter來搜索數(shù)據(jù)及filter執(zhí)行原理深度剖析(bitset機(jī)制與caching機(jī)制)

1、term filters搜索

(1)插入一些測(cè)試帖子數(shù)據(jù)

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

現(xiàn)在es 5.2版本,type=text,默認(rèn)會(huì)設(shè)置兩個(gè)field,一個(gè)是field本身,比如articleID,就是分詞的;還有一個(gè)的話,就是field.keyword,articleID.keyword,默認(rèn)不分詞,會(huì)最多保留256個(gè)字符

(2)根據(jù)用戶ID搜索帖子

GET /forum/article/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"userID" : 1
}
}
}
}
}
term filter/query:對(duì)搜索文本不分詞,直接拿去倒排索引中匹配,你輸入的是什么,就去匹配什么

(3)根據(jù)帖子ID搜索帖子

GET /forum/article/_search
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"articleID" : "XHDK-A-1293-#fJ3"
}
}
}
}
}
查不到數(shù)據(jù),因?yàn)槟J(rèn)是analyzed的text類型的field,建立倒排索引的時(shí)候,就會(huì)對(duì)所有的articleID分詞,分詞以后,原本的articleID就沒有了,只有分詞后的各個(gè)word存在于倒排索引中。
(4)重建索引或者使用內(nèi)至的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)梳理學(xué)到的知識(shí)點(diǎn)
(1)term filter:根據(jù)exact value進(jìn)行搜索,數(shù)字、boolean、date天然支持
(2)text需要建索引時(shí)指定為not_analyzed,才能用term query
2、filter執(zhí)行原理深度剖析(bitset機(jī)制與caching機(jī)制)

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

date來舉例

word doc1 doc2 doc3

2017-01-01 * *
2017-02-02 * *
2017-03-03 * * *

filter:2017-02-02

到倒排索引中一找,發(fā)現(xiàn)2017-02-02對(duì)應(yīng)的document list是doc2,doc3

(2)為每個(gè)在倒排索引中搜索到的結(jié)果,構(gòu)建一個(gè)bitset,[0, 0, 0, 1, 0, 1]

非常重要

使用找到的doc list,構(gòu)建一個(gè)bitset,就是一個(gè)二進(jìn)制的數(shù)組,數(shù)組每個(gè)元素都是0或1,用來標(biāo)識(shí)一個(gè)doc對(duì)一個(gè)filter條件是否匹配,如果匹配就是1,不匹配就是0

[0, 1, 1]

doc1:不匹配這個(gè)filter的
doc2和do3:是匹配這個(gè)filter的

(3)遍歷每個(gè)過濾條件對(duì)應(yīng)的bitset,優(yōu)先從最稀疏的開始搜索,查找滿足所有條件的document

后面會(huì)講解,一次性其實(shí)可以在一個(gè)search請(qǐng)求中,發(fā)出多個(gè)filter條件,每個(gè)filter條件都會(huì)對(duì)應(yīng)一個(gè)bitset,遍歷每個(gè)filter條件對(duì)應(yīng)的bitset,先從最稀疏的開始遍歷,就可以先過濾掉盡可能多的數(shù)據(jù)

[0, 0, 0, 1, 0, 0]:比較稀疏
[0, 1, 0, 1, 0, 1]
請(qǐng)求:filter,postDate=2017-01-01,userID=1
postDate: [0, 0, 1, 1, 0, 0]
userID: [0, 1, 0, 1, 0, 1]

遍歷完兩個(gè)bitset之后,找到的匹配所有條件的doc,比如就是doc4

就可以將document作為結(jié)果返回給client了

(4)caching bitset,跟蹤query,在最近256個(gè)query中超過一定次數(shù)的過濾條件,緩存其bitset。對(duì)于小segment(<1000,或<3%),不緩存bitset。

segment數(shù)據(jù)量很小,此時(shí)哪怕是掃描也很快;segment會(huì)在后臺(tái)自動(dòng)合并,小segment很快就會(huì)跟其他小segment合并成大segment,此時(shí)就緩存也沒有什么意義,segment很快就消失了

比如postDate=2017-01-01,[0, 0, 1, 1, 0, 0],可以緩存在內(nèi)存中,這樣下次如果再有這個(gè)條件過來的時(shí)候,就不用重新掃描倒排索引,反復(fù)生成bitset,可以大幅度提升性能。

在最近的256個(gè)filter中,有某個(gè)filter超過了一定的次數(shù),次數(shù)不固定,就會(huì)自動(dòng)緩存這個(gè)filter對(duì)應(yīng)的bitset

filter比query的好處就在于會(huì)caching,但是之前不知道caching的是什么東西,實(shí)際上并不是一個(gè)filter返回的完整的doc list數(shù)據(jù)結(jié)果。而是filter bitset緩存起來。下次不用掃描倒排索引了。

(5)filter大部分情況下來說,在query之前執(zhí)行,先盡量過濾掉盡可能多的數(shù)據(jù)

query:是會(huì)計(jì)算doc對(duì)搜索條件的relevance score,還會(huì)根據(jù)這個(gè)score去排序
filter:只是簡(jiǎn)單過濾出想要的數(shù)據(jù),不計(jì)算relevance score,也不排序

(6)如果document有新增或修改,那么cached bitset會(huì)被自動(dòng)更新

(7)以后只要是有相同的filter條件的,會(huì)直接來使用這個(gè)過濾條件對(duì)應(yīng)的cached bitset

3、基于bool組合多個(gè)filter條件來搜索數(shù)據(jù)
(1)搜索發(fā)帖日期為2017-01-01,或者帖子ID為XHDK-A-1293-#fJ3的帖子,同時(shí)要求帖子的發(fā)帖日期絕對(duì)不為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,必須匹配,可以匹配其中任意一個(gè)即可,必須不匹配
(2)搜索帖子ID為XHDK-A-1293-#fJ3,或者是帖子ID為JODL-X-1937-#pV7而且發(fā)帖日期為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"
                    }
                  }
                  ]
              }
            }
            
            
            ]
        }
      }
    }
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容