[elasticsearch] match 和 term search 的差別,做 like 模糊搜尋?

elasticsearch 是一個做全文索引很好用的資料庫(本篇已套用 ik 分詞器,因此非預設的一字一索引)

因此最近試著用 elasticsearch 時,官方預設的使用 search api 搜尋資料使用例子:

搜尋 title中正大學 用法:

curl -XGET 'http://localhost:9200/news_index/news_type/_search?q=title:中正大學'

你可能會找到 title 包含有中正大學的資料

如:

title: “中正大學:補助經費總被漏 師生心痛”
url: “www.ccu…..”
content: “….. etc”

但將搜尋到結果,隨著 score 分數越低,你會發現好像和你的 query 想要的結果不太一樣

我們試著搜尋較長的句子(“國立中正大學生活事務組”)如下例:

curl -XGET 'http://localhost:9200/news_index/news_type/_search?q=title:國立中正大學生活事務組'

你會發現搜尋到的結果,title 很有可能不會包含我們搜尋的句子 “國立中正大學生活事務組”

如:

title: “自由自在多采多姿大學生活 75%滿意”
url: “www.ettoday…..”
content: “….. etc”

符合搜尋結果的資料,看起來似乎是符合了”大學生活”

我們嘗試探究真正符合的區塊究竟是哪裡,試著下以下 query

PS. search api 其實預設就是 match search ,所以這邊的 query 使用 match 來搜尋:

curl -XGET 'http://localhost:9200/news/type_news/_search?pretty=true' -d '{"query" : {"match":{"title":" 中正大學"}}, "highlight": {"pre_tags":["<h1>"], "post_tags":["</h1>"], "fields":{ "*": {} }} }'

 

PS. 詳細的 payload,使用 match search ,將 match 的索引前後加上 <h1> tag

{
“query”: {
“match”: {
“title”: ” 中正大學生活事務組”
}
},
“highlight”: {
“pre_tags”: [“<h1>”],
“post_tags”: [“</h1>”],
“fields”: {
“*”: {}
}
}
}

從這邊你可以發現,上面範例的符合搜尋的詞為 “大學生活”

因此我們可以知道預設的 search 也就是 match search , 會針對搜尋的句子會做分詞(若為預設分詞器,則為一個字一詞)

做完分詞後,在使用這些分詞去搜尋索引。若有符合任一索引(這邊其實可以透過 minimum_should_match 參數,調整你希望至少符合多少個分詞索引),則回傳回來。

看到這邊,你會發現那要如何做以前 mysql 使用的 like 模糊搜尋

其實就是現在要說的 term search 囉!

我們試著用以下例子:

curl -XGET 'http://localhost:9200/news/type_news/_search?pretty=true' -d '{"query" : {"term":{"title":"中正大學生活事務組"}}, "highlight": {"pre_tags":["<h1>"], "post_tags":["</h1>"], "fields":{ "*": {} }} }'

找出在 title 欄位中含有 “中正大學生活事務組” 索引的資料

會發現和 match search 不同,會直接拿 “中正大學生活事務組” 去尋找擁有此索引的資料。(不會預先做分詞)

當然,若沒裝分詞器的話,由於並未適當的建分詞索引,其實 term search 反而會找不到東西唷!

Leave a Reply