Elasticsearch的Term為什麼很快之跳錶
- 2020 年 3 月 31 日
- 筆記
term代表完全匹配,也就是精確查詢,搜索前不會再對搜索詞進行分詞,所以我們的搜索詞必須是文檔分詞集合中的一個,此欄位如 "無分詞",則完全匹配此欄位(如果對於某個欄位,你想精確匹配,即搜索什麼詞匹配什麼詞,類似sql中的=操作,則應該採取此操作),下面是用的kibana的示例數據的Term操作。
GET kibana_sample_data_ecommerce/_search { "query": { "bool": { "must": [{ "term": { "customer_first_name.keyword": { "value": "Mary" } } }, { "term": { "customer_gender": { "value": "FEMALE" } } } ] } } }
假設我們有以下數據:
docId |
customer_first_name |
customer_gender |
---|---|---|
1 |
Marry |
FEMALE |
2 |
Shen |
MALE |
3 |
Marry |
FEMALE |
這裡每一行是一個document。每個document都有一個docid。那麼給這些document建立的倒排索引就是:
customer_first_name
Marry |
[1,3] |
---|---|
Shen |
[2] |
customer_gender
FEMALE |
[1,3] |
---|---|
MALE |
[2] |
可以看到,倒排索引是按欄位的,一個欄位有一個自己的倒排索引。Marry,Shen這些叫做 term,而[1,3]就是posting list。Posting list就是一個int的數組,存儲了所有符合某個term的文檔id。
利用 Skip List 合併

以上是三個posting list。我們現在需要把它們用AND的關係合併,得出posting list的交集。首先選擇最短的posting list,然後從小到大遍歷。遍歷的過程可以跳過一些元素,比如我們遍歷到綠色的13的時候,就可以跳過藍色的3了,因為3比13要小。
整個過程如下
Next -> 2 Advance(2) -> 13 Advance(13) -> 13 Already on 13 Advance(13) -> 13 MATCH!!! Next -> 17 Advance(17) -> 22 Advance(22) -> 98 Advance(98) -> 98 Advance(98) -> 98 MATCH!!!
最後得出的交集是[13,98],所需的時間比完整遍歷三個posting list要快得多。但是前提是每個list需要指出Advance這個操作。Advance操作是什麼?就是 skip list 提供的快速跳躍的特性。