Skip to content

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

Published: at 10:38 AM

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

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

搜尋 title中正大學 用法:

[code] curl -XGET ‘http://localhost:9200/news_index/news_type/\_search?q=title:中正大學’ [/code]

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

如:

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

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

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

[code] curl -XGET ‘http://localhost:9200/news_index/news_type/\_search?q=title:國立中正大學生活事務組’ [/code]

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

如:

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

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

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

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

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

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

tag

{ “query”: { “match”: { “title”: ” 中正大學生活事務組” } }, “highlight”: { “pre_tags”: ["

"], “post_tags”: ["

"], “fields”: { ”*”: {} } } }

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

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

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

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

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

我們試著用以下例子:

[code] curl -XGET ‘http://localhost:9200/news/type_news/\_search?pretty=true’ -d ’{“query” : {“term”:{“title”:“中正大學生活事務組”}}, “highlight”: {“pre_tags”:["

"], “post_tags”:["

"], “fields”:{ ”*”: {} }} }’ [/code]

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

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

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