天天看點

再談Elasticsearch全文搜尋:你不知道的query_string、match、term、match_phrase的差別

再談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":"中國科學院計算研究所"}

           
再談Elasticsearch全文搜尋:你不知道的query_string、match、term、match_phrase的差別

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字段的分詞結果中,

不考慮順序

繼續閱讀