天天看點

Kibana搜尋原理1. 背景2. 關于Kibana的正規表達式3. 資料字段類型4. mapping5. analyze6. 簡單實踐

注:本文基于Kibana 7.13.4版本

1. 背景

在上一篇文章——Kibana常用搜尋文法,我們簡單介紹了kibana的常用搜尋文法,但在實際使用中,總是出現各種異常,為什麼明明存在的字元串就是比對不到,搜不出來,今天我們就來稍微深入下Kibana的搜尋原理。

2. 關于Kibana的正規表達式

因為Kibana的正規表達式引擎并不是使用perl pcre,是以有一些正則并不支援,比如開頭和結尾錨定符号,^和$,詳細的支援符号可以檢視官方文檔,https://www.elastic.co/guide/en/elasticsearch/reference/7.13/regexp-syntax.html

3. 資料字段類型

我們的日志,每個字段都有對應的資料類型,而不同的資料類型也決定了該字段的搜尋屬性,比如是否允許全文搜尋。關于Kibana支援的資料類型可以參考官方文檔,https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html。

我們今天主要來看下text類型和keyword類型,這兩個類型也是導緻我們搜尋結果不符合預期的主要原因。

  • keyword

    保留字段原格式,不進行解析,搜尋時需要比對到整個字段,比如對于一個字段為"how are you",你無法用how或者are來搜尋,隻能用完整的“how are you”來搜尋,或者使用正則和通配符,比如how*

  • text

    可以被分析,也就是能支援全文搜尋,比如對于一個字段為"how are you",它就會被解析為

“how” "are" "you"
           

那我們搜尋時,就可以通過這三個詞中的任意一個來搜尋

4. mapping

既然每個字段都有對應的類型,那如何确定或者如何設定某個字段的類型呢,這就需要通過mapping。所謂mapping就是将傳入的日志通過一定規則将每個字段映射成對應的類型。而這個規則就是我們需要關注的。

我們可以通過Kibana的Dev Tools來建立index并設定對應的mapping規則,

PUT mytest
{
  "mappings": {
    "properties": {
      "message1": {
        "type": "text"
      },
      "message2": {
        "type": "keyword"
      }
    }
  }
}
           

如上,我們定義了新的index為mytest,有兩個字段,分别是text類型的message1和keyword類型的message2。對于已存在的index,我們可以通過get方式擷取詳細的mapping規則,

GET /mytest/_mapping
           

5. analyze

上面我們說到,對于text類型的字段是可解析的,可以被全文搜尋,那我們又如何來确定這個全文搜尋的最小粒度呢。比如“how are you”這個文本我們很好了解,最小粒度就是一個單詞。但如果對于複雜一些的字元串呢,比如“/var/log/yum.log”。這就涉及到分詞,也就是對字元串的解析。Kibana預設的分析器為standard analyzer,其遵循的分詞規範為Unicode® Standard Annex #29,具體規則我們不細說。我們主要是關注分詞的結果,同樣可以通過Kibana的Dev Tools來測試。

可以通過以下方式擷取指定文本的解析分詞結果,用GET請求也一樣。

POST _analyze
{
  "analyzer": "standard",
  "text": "/var/log/yum.log"
}
           

有結果可知,這個文本被分為三部分,是以我們搜尋該文本時,應該用yum.log,而不是yum,否則就搜尋不到

Kibana搜尋原理1. 背景2. 關于Kibana的正規表達式3. 資料字段類型4. mapping5. analyze6. 簡單實踐

6. 簡單實踐

說完這些,我們通過一個小例子來說明,這樣了解起來比較直接。需要注意的是,以下測試都是在Lucene開啟的情況下測試。

首先我們以第四部分的mapping為例子,建立mytest索引和mapping規則,然後我們建立幾條資料,用于接下來的測試,

PUT mytest/_doc/1?refresh
{
  "message1": "hello world",
  "message2":"how are you" 
} 

PUT mytest/_doc/2?refresh
{
  "message1": "how are you",
  "message2":"hello world" 
} 

PUT mytest/_doc/3?refresh
{
  "message1": "/var/log/yum.log",
  "message2":"path" 
} 
           

然後我們建立index pattern,把mytest導入,就能看到這三條文檔,

Kibana搜尋原理1. 背景2. 關于Kibana的正規表達式3. 資料字段類型4. mapping5. analyze6. 簡單實踐

這樣我們就可以開始我們的測試了。

  • text
message1:helloworld #傳回第一條文檔
           
message1:hello #無文檔傳回
           
message1:how #傳回第二條文檔
           
message1:are #傳回第二條文檔
           
message1:var #傳回第三條文檔
           
message1:yum.log #傳回第三條文檔
           
message1:yum #無文檔傳回
           
message1:yum* #傳回第三條文檔
           
  • keyword
message2:"how are you" #傳回第一條文檔
           
message2:how #無文檔傳回
           
message2:how* #傳回第一條文檔
           
message2:are* #無文檔傳回
           
message2:*are* #傳回第一條文檔
           
message2:helloworld #傳回第二條文檔
           

參考文檔:

  1. https://stackoverflow.com/questions/52908780/kibana-using-regex-doesnt-work-as-expected
  2. https://www.elastic.co/guide/en/elasticsearch/reference/7.13/regexp-syntax.html
  3. https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
  4. https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-analyze.html
下一篇: BLE 信道

繼續閱讀