再談Elasticsearch全文搜尋:你不知道的query_string、match、term、match_phrase的差別
-
- match和term差別
-
- 1.term查詢keyword字段
- 2.term查詢text字段
- 3.match查詢keyword字段
- 4.match查詢text字段
- match_phrase和query_string的差別
-
- 1.match_phrase查詢keyword字段
- 2.match_phrase查詢text字段
- 3.query_string查詢keyword字段
- 4.query_string查詢text字段
- 總結
match和term差別
在講解
match
和
term
差別之前先來說明一下
text
和
keyword
的差別,簡單一句話就是
text
支援預設分詞,
keyword
不支援分詞。
建立索引:
{
"settings": {
"index": {
"number_of_shards": "1",
"number_of_replicas": "0"
}
},
"mappings": {
"properties": {
"title": {
"type": "keyword"
},
"content": {
"type": "text",
"analyzer":"ik_max_word"
}
}
}
}
添加資料:
{"index":{"_index":"test"}}
{"title":"測試一下","content":"Elasticsearch中query_string、match、term的差別"}
{"index":{"_index":"test"}}
{"title":"中國人民","content":"中國科學院計算研究所"}
1.term查詢keyword字段
term不分詞,keyword也不會分詞,是以需要完全比對才能夠查詢到結果
{
"query":{
"term":{
"title":"測試一下"
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
查詢結果:
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "JcSuJG0BGg18gZ2OHMqK",
"_score": 0.6931472,
"_source": {
"title": "測試一下",
"content": "Elasticsearch中query_string、match、term的差別"
},
"highlight": {
"title": [
"<em>測試一下</em>"
]
}
}
]
如果隻查詢
測試
是查不到的。
2.term查詢text字段
雖然term不分詞,但是text支援分詞,查詢條件可以是text分詞後的任一個詞。
{
"query":{
"term":{
"content":"研究所"
}
},
"highlight": {
"fields": {
"content": {}
}
}
}
查詢結果:
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "JsSuJG0BGg18gZ2OHMqK",
"_score": 0.6931472,
"_source": {
"title": "中國人民",
"content": "中國科學院計算研究所"
},
"highlight": {
"content": [
"中國科學院計算<em>研究所</em>"
]
}
}
]
采用下面的請求分析一下
中國科學院計算研究所
被分成了哪些詞:
post http:127.0.0.1:9200/_analyze
{
"analyzer":"ik_max_word",
"text":"中國科學院計算研究所"
}
傳回的分詞結果為:
[中國科學院,中國,科學院,科學,學院,計算,研究所,研究,所]
也就是說以上面的任一個為搜尋條件都可以搜尋到這條資料。
假如使用
國科
是查不到的,同樣,使用
中國科學院計算研究所
也是查不出結果的,因為以及被分詞了。
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": []
}
}
3.match查詢keyword字段
match會被分詞,但是keyword不會被分詞,是以查詢條件依然要完全比對:
{
"query":{
"match":{
"title":"中國人民"
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
查詢結果:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.6931472,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "JsSuJG0BGg18gZ2OHMqK",
"_score": 0.6931472,
"_source": {
"title": "中國人民",
"content": "中國科學院計算研究所"
},
"highlight": {
"title": [
"<em>中國人民</em>"
]
}
}
]
}
}
隻有這一個查詢條件可以成功,其他的都會失敗。
4.match查詢text字段
match
和
text
都支援分詞,是以隻要match分詞結果和text的分詞結果有相同的,就可以查詢出來。
{
"query":{
"match":{
"content":"中國"
}
},
"highlight": {
"fields": {
"content": {}
}
}
}
查詢結果:
{
"took": 19,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.6931472,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "JsSuJG0BGg18gZ2OHMqK",
"_score": 0.6931472,
"_source": {
"title": "中國人民",
"content": "中國科學院計算研究所"
},
"highlight": {
"content": [
"<em>中國</em>科學院計算研究所"
]
}
}
]
}
}
可以看出,因為
中國科學院計算研究所
的分詞結果包含
中國
,是以隻使用
中國
就可以查詢到。如果查詢條件是
加油中國
或
中國必勝
,隻要是分詞結果中含有
中國
的都可以查詢出來。同樣,對于其他的分詞也是一樣。
match_phrase和query_string的差別
1.match_phrase查詢keyword字段
keyword不支援分詞,是以需要完全比對才可以
{
"query":{
"match_phrase":{
"title":"中國人民"
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
2.match_phrase查詢text字段
match_phrase是分詞的,text也是分詞的。match_phrase的分詞結果必須在text字段分詞中都包含,而且順序必須相同,而且必須都是連續的。
{
"query":{
"match_phrase":{
"content":"中國"
}
},
"highlight": {
"fields": {
"content": {}
}
}
}
上面的條件可以查出來,但是換成
中國加油
就不可以了,因為
加油
不包含在
content
的分詞中。
中國研究所
也不可以,雖然它的分詞
中國
和
研究所
都在cotent的分詞中,但是由于不連續,是以也是查詢不出來的。
3.query_string查詢keyword字段
必須全比對
{
"query":{
"query_string":{
"query":"中國人民",
"fields":["title"]
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
查詢結果:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.6931472,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "JsSuJG0BGg18gZ2OHMqK",
"_score": 0.6931472,
"_source": {
"title": "中國人民",
"content": "中國科學院計算研究所"
},
"highlight": {
"title": [
"<em>中國人民</em>"
]
}
}
]
}
}
4.query_string查詢text字段
query_string查詢text字段,隻要query_string中的分詞結果有一個在text字段的分詞結果中就可以查詢出來,多個時也不用考慮順序。
{
"query":{
"query_string":{
"query":"中國",
"fields":["title","content"]
}
},
"highlight": {
"fields": {
"title": {},
"content":{}
}
}
}
查詢結果:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.6931472,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "JsSuJG0BGg18gZ2OHMqK",
"_score": 0.6931472,
"_source": {
"title": "中國人民",
"content": "中國科學院計算研究所"
},
"highlight": {
"content": [
"<em>中國</em>科學院計算研究所"
]
}
}
]
}
}
下面的查詢也可以
{
"query":{
"query_string":{
"query":"研究所中國加油",
"fields":["title","content"]
}
},
"highlight": {
"fields": {
"title": {},
"content":{}
}
}
}
查詢結果:
......
"highlight": {
"content": [
"<em>中國</em>科學院計算<em>研究</em><em>所</em>"
]
}
總結
關鍵詞 | keyword類型 | text類型 | 是否支援分詞 |
---|---|---|---|
term | 完全比對 | 查詢條件 text分詞中的,且不能多餘,多個分詞時 ,順序不能颠倒。 | 否 |
match | 完全比對 | match分詞結果和text的分詞結果 的即可, | 是 |
match_phrase | 完全比對 | match_phrase的分詞結果必須在text字段分詞中 ,而且順序必須相同,而且必須 的。 | 是 |
query_string | 完全比對 | query_string中的分詞結果 在text字段的分詞結果中, | 是 |