ES[7.6.x]學習筆記(六)分析器

在前面的章節中,我們給大家介紹了索引中的映射類型,也就是每一個字段都有一個類型,比如:long,text,date等。這和我們的數據庫非常的相似,那麼它的不同之處是什麼呢?對了,就是全文索引,在ES當中,只有text類型的字段纔會用的全文索引,那麼這裏就會引出ES中一個非常重要的概念,文本分析器(Text analysis)

分析器使ES支持全文索引,搜索的結果是和你搜索的內容相關的,而不是你搜索內容的確切匹配。我們用ES官網中的例子給大家舉例,假如你在搜索框中輸入的內容是Quick fox jumps,你想得到的結果是A quick brown fox jumps over the lazy dog,或者結果中包含這樣的詞fast foxfoxes leap

分析器之所以能夠使搜索支持全文索引,都是因爲有分詞器(tokenization),它可以將一句話、一篇文章切分成不同的詞語,每個詞語都是獨立的。假如你在ES索引中添加了一條記錄the quick brown fox jumps,而用戶搜索時輸入的內容是quick fox,並沒有完全匹配的內容,但是因爲有了分詞器,你索引的內容被切分成了不同的、獨立的詞,用戶搜索的內容也會進行相應的切分,所以用戶搜索的內容雖然沒有完全匹配,但也能夠搜索到想要的內容。

分析器除了要做分詞,還要做歸一化(Normalization)。分詞器能夠使搜索內容在每一個詞上匹配,但這種匹配也只是在字面上進行的匹配。

  • 比如你搜索Quick,但是不能匹配到quick,它們的大小寫不同。
  • 比如你搜索fox,但是不能匹配到foxes,它是複數形式。
  • 比如你搜索jumps,不能匹配到leaps,雖然它們是同義詞。

爲了解決這些問題,分析器要把這些分詞歸一化到標準的格式。這樣我們在搜索的時候就不用嚴格的匹配了,相似的詞語我們也能夠檢索出來,上面的3種情況,我們也能夠搜索出相應的結果。

分析器的組成

分析器,無論是內置的,還是自定義的,都是由3部分組成:字符過濾器(character filters)、分詞器(tokenizers)、分詞過濾器(token filters)。

字符過濾器

字符過濾器接收最原始的文檔,並且可以改變其內容,比如:可以把中文的一二三四五六七八九,變成阿拉伯數字123456789。它還可以過濾html標籤,並對其進行轉義。還可以通過正則表達式,把匹配到的內容轉化成其他的內容。一個分析器可以有多個字符過濾器,也可以沒有字符過濾器。

分詞器

一個分析器只能有一個確定的分詞器,它可以把一句話分成若干個詞,比如:空格分詞器。當你輸入一句話Quick brown fox!,它將被切分成[Quick, brown, fox!]

分詞過濾器

分詞過濾器接收分詞並且可以改變分詞,比如:小寫分詞過濾器,它將接收到的分詞全部轉換成小寫。助詞過濾器,它將刪除掉一些公共的助詞,比如英語裏的 theisare等,中文裏的等。同義詞過濾器,它將在你的分詞中,添加相應的同義詞。一個分析器可以有多個分詞過濾器,它們將按順序執行。

我們在建立索引和搜索時,都會用的分析器。

配置文本分析器

前面我們講了分析器的基本概念,也瞭解了全文搜索的基本步驟。下面我們看一下如何配置文本分析器,ES默認給我們配置的分析器是標準分析器。如果標準的分析器不適合你,你可以指定其他的分析器,或者自定義一個分析器。

ES有分析器的api,我們指定分析器和文本內容,就可以得到分詞的結果。比如:

POST _analyze
{
  "analyzer": "whitespace",
  "text":     "The quick brown fox."
}

返回的結果如下:

{
    "tokens": [
        {
            "token": "The",
            "start_offset": 0,
            "end_offset": 3,
            "type": "word",
            "position": 0
        },
        {
            "token": "quick",
            "start_offset": 4,
            "end_offset": 9,
            "type": "word",
            "position": 1
        },
        {
            "token": "brown",
            "start_offset": 10,
            "end_offset": 15,
            "type": "word",
            "position": 2
        },
        {
            "token": "fox.",
            "start_offset": 16,
            "end_offset": 20,
            "type": "word",
            "position": 3
        }
    ]
}

我們指定的分析器是空格分析器,輸入的文本內容是The quick brown fox.,返回結果是用空格切分的四個詞。我們也可以測試分析器的組合,比如:

POST _analyze
{
  "tokenizer": "standard",
  "filter":  [ "lowercase", "asciifolding" ],
  "text":      "Is this déja vu?"
}

我們指定了標準的分詞器,小寫過濾器和asciifolding過濾器。輸入的內容是Is this déja vu?,我們執行一下,得到如下的結果:

{
    "tokens": [
        {
            "token": "is",
            "start_offset": 0,
            "end_offset": 2,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "this",
            "start_offset": 3,
            "end_offset": 7,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "deja",
            "start_offset": 8,
            "end_offset": 12,
            "type": "<ALPHANUM>",
            "position": 2
        },
        {
            "token": "vu",
            "start_offset": 13,
            "end_offset": 15,
            "type": "<ALPHANUM>",
            "position": 3
        }
    ]
}

我們可以看到結果中,is變成了小寫,déja變成了deja,最後的?也過濾掉了。

爲指定的字段配置分析器

我們在創建映射時,可以爲每一個text類型的字段指定分析器,例如:

PUT my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "whitespace"
      }
    }
  }
}

我們在my_index索引中,創建了title字段,它的類型是text,它的分析器是whitespace空格分析器。

爲索引指定默認的分析器

如果我們覺得爲每一個字段指定分析器過於麻煩,我們還可以爲索引指定一個默認的分詞器,如下:

PUT my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "whitespace"
        }
      }
    }
  }
}

我們爲my_index索引指定了默認的分析器whitespace。這樣我們在創建text類型的字段時,就不用爲其指定分析器了。

這一節給大家介紹了分析器,我們可以看到例子中都是使用的英文分析器,下一節我們一起看一下強大的中文分析器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章