一、ik_max_wordjavascript
會將文本作最細粒度的拆分,好比會將「中華人民共和國人民大會堂」拆分爲「中華人民共和國、中華人民、中華、華人、人民共和國、人民、共和國、大會堂、大會、會堂等詞語。java
二、ik_smart
會作最粗粒度的拆分,好比會將「中華人民共和國人民大會堂」拆分爲中華人民共和國、人民大會堂。
elasticsearch
term
和 match
總結在實際的項目查詢中,term
和match
是最經常使用的兩個查詢,而常常搞不清二者有什麼區別,趁機總結有空總結下。code
term
用法token
先看看term的定義,term是表明徹底匹配,也就是精確查詢,搜索前不會再對搜索詞進行分詞拆解。ip
這裏經過例子來講明,先存放一些數據:文檔
{ "title": "love China", "content": "people very love China", "tags": ["China", "love"] } { "title": "love HuBei", "content": "people very love HuBei", "tags": ["HuBei", "love"] }
來使用term
查詢下:it
{ "query": { "term": { "title": "love" } } }
結果是,上面的兩條數據都能查詢到:io
{ "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 0.6931472, "hits": [ { "_index": "test", "_type": "doc", "_id": "8", "_score": 0.6931472, "_source": { "title": "love HuBei", "content": "people very love HuBei", "tags": ["HuBei","love"] } }, { "_index": "test", "_type": "doc", "_id": "7", "_score": 0.6931472, "_source": { "title": "love China", "content": "people very love China", "tags": ["China","love"] } } ] } }
發現,title裏有關love的關鍵字都查出來了,可是我只想精確匹配 love China
這個,按照下面的寫法看看能不能查出來:ast
{ "query": { "term": { "title": "love China" } } }
執行發現無數據,從概念上看,term屬於精確匹配,只能查單個詞。我想用term匹配多個詞怎麼作?可使用terms
來:
{ "query": { "terms": { "title": ["love", "China"] } } }
查詢結果爲:
{ "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 0.6931472, "hits": [ { "_index": "test", "_type": "doc", "_id": "8", "_score": 0.6931472, "_source": { "title": "love HuBei", "content": "people very love HuBei", "tags": ["HuBei","love"] } }, { "_index": "test", "_type": "doc", "_id": "7", "_score": 0.6931472, "_source": { "title": "love China", "content": "people very love China", "tags": ["China","love"] } } ] } }
發現所有查詢出來,爲何?由於terms裏的[ ]
多個是或者的關係,只要知足其中一個詞就能夠。想要通知知足兩個詞的話,就得使用bool的must來作,以下:
{ "query": { "bool": { "must": [ { "term": { "title": "love" } }, { "term": { "title": "china" } } ] } } }
能夠看到,咱們上面使用china
是小寫的。當使用的是大寫的China
咱們進行搜索的時候,發現搜不到任何信息。這是爲何了?title這個詞在進行存儲的時候,進行了分詞處理。咱們這裏使用的是默認的分詞處理器進行了分詞處理。咱們能夠看看如何進行分詞處理的?
分詞處理器
GET test/_analyze { "text" : "love China" }
結果爲:
{ "tokens": [ { "token": "love", "start_offset": 0, "end_offset": 4, "type": "<ALPHANUM>", "position": 0 }, { "token": "china", "start_offset": 5, "end_offset": 10, "type": "<ALPHANUM>", "position": 1 } ] }
分析出來的爲love
和china
的兩個詞。而term
只能完完整整的匹配上面的詞,不作任何改變的匹配。因此,咱們使用China
這樣的方式進行的查詢的時候,就會失敗。稍後會有一節專門講解分詞器。
match
用法
先用 love China
來匹配。
GET test/doc/_search { "query": { "match": { "title": "love China" } } }
結果是:
{ "took": 1, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 1.3862944, "hits": [ { "_index": "test", "_type": "doc", "_id": "7", "_score": 1.3862944, "_source": { "title": "love China", "content": "people very love China", "tags": [ "China", "love" ] } }, { "_index": "test", "_type": "doc", "_id": "8", "_score": 0.6931472, "_source": { "title": "love HuBei", "content": "people very love HuBei", "tags": [ "HuBei", "love" ] } } ] } }
發現兩個都查出來了,爲何?由於match進行搜索的時候,會先進行分詞拆分,拆完後,再來匹配,上面兩個內容,他們title的詞條爲: love china hubei
,咱們搜索的爲love China
咱們進行分詞處理獲得爲love china
,而且屬於或的關係,只要任何一個詞條在裏面就能匹配到。若是想 love
和 China
同時匹配到的話,怎麼作?使用 match_phrase
match_phrase
用法
match_phrase
稱爲短語搜索,要求全部的分詞必須同時出如今文檔中,同時位置必須緊鄰一致。
GET test/doc/_search { "query": { "match_phrase": { "title": "love china" } } }
結果爲:
{ "took": 5, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 1.3862944, "hits": [ { "_index": "test", "_type": "doc", "_id": "7", "_score": 1.3862944, "_source": { "title": "love China", "content": "people very love China", "tags": [ "China", "love" ] } } ] } }
此次好像符合咱們的需求了,結果只出現了一條記錄。
Bool查詢對應Lucene中的BooleanQuery,它由一個或者多個子句組成,每一個子句都有特定的類型。
minimum_should_match
參數定義了至少知足幾個子句。
bool查詢也支持禁用協同計分選項disable_coord。通常計算分值的因素取決於全部的查詢條件。
bool查詢也是採用more_matches_is_better的機制,所以知足must和should子句的文檔將會合並起來計算分值。
{ "bool" : { "must" : { "term" : { "user" : "kimchy" } }, "filter": { "term" : { "tag" : "tech" } }, "must_not" : { "range" : { "age" : { "from" : 10, "to" : 20 } } }, "should" : [ { "term" : { "tag" : "wow" } }, { "term" : { "tag" : "elasticsearch" } } ], "minimum_should_match" : 1, "boost" : 1.0 } }
在filter子句查詢中,分值將會都返回0。分值會受特定的查詢影響。
好比,下面三個查詢中都是返回全部status字段爲active的文檔
第一個查詢,全部的文檔都會返回0:
GET _search { "query": { "bool": { "filter": { "term": { "status": "active" } } } } }
下面的bool查詢中包含了一個match_all,所以全部的文檔都會返回1
GET _search { "query": { "bool": { "must": { "match_all": {} }, "filter": { "term": { "status": "active" } } } } }
constant_score與上面的查詢結果相同,也會給每一個文檔返回1:
GET _search { "query": { "constant_score": { "filter": { "term": { "status": "active" } } } } }
若是想知道究竟是bool裏面哪一個條件匹配,可使用named query查詢:
{ "bool" : { "should" : [ {"match" : { "name.first" : {"query" : "shay", "_name" : "first"} }}, {"match" : { "name.last" : {"query" : "banon", "_name" : "last"} }} ], "filter" : { "terms" : { "name.last" : ["banon", "kimchy"], "_name" : "test" } } } }