在讲解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":"中国科学院计算研究所"}
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": [
"测试一下"
]
}
}
]
如果只查询测试
是查不到的。
虽然term不分词,但是text支持分词,查询条件可以是text分词后的任一个词。
{
"query":{
"term":{
"content":"研究所"
}
},
"highlight": {
"fields": {
"content": {}
}
}
}
查询结果:
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "JsSuJG0BGg18gZ2OHMqK",
"_score": 0.6931472,
"_source": {
"title": "中国人民",
"content": "中国科学院计算研究所"
},
"highlight": {
"content": [
"中国科学院计算研究所"
]
}
}
]
采用下面的请求分析一下中国科学院计算研究所
被分成了哪些词:
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": []
}
}
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": [
"中国人民"
]
}
}
]
}
}
只有这一个查询条件可以成功,其他的都会失败。
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": [
"中国科学院计算研究所"
]
}
}
]
}
}
可以看出,因为中国科学院计算研究所
的分词结果包含中国
,所以只使用中国
就可以查询到。如果查询条件是加油中国
或中国必胜
,只要是分词结果中含有中国
的都可以查询出来。同样,对于其他的分词也是一样。
keyword不支持分词,所以需要完全匹配才可以
{
"query":{
"match_phrase":{
"title":"中国人民"
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
match_phrase是分词的,text也是分词的。match_phrase的分词结果必须在text字段分词中都包含,而且顺序必须相同,而且必须都是连续的。
{
"query":{
"match_phrase":{
"content":"中国"
}
},
"highlight": {
"fields": {
"content": {}
}
}
}
上面的条件可以查出来,但是换成中国加油
就不可以了,因为加油
不包含在content
的分词中。中国研究所
也不可以,虽然它的分词中国
和研究所
都在cotent的分词中,但是由于不连续,所以也是查询不出来的。
必须全匹配
{
"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": [
"中国人民"
]
}
}
]
}
}
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": [
"中国科学院计算研究所"
]
}
}
]
}
}
下面的查询也可以
{
"query":{
"query_string":{
"query":"研究所中国加油",
"fields":["title","content"]
}
},
"highlight": {
"fields": {
"title": {},
"content":{}
}
}
}
查询结果:
......
"highlight": {
"content": [
"中国科学院计算研究所"
]
}
关键词 | keyword类型 | text类型 | 是否支持分词 |
---|---|---|---|
term | 完全匹配 | 查询条件必须都是 text分词中的,且不能多余,多个分词时必须连续 ,顺序不能颠倒。 |
否 |
match | 完全匹配 | match分词结果和text的分词结果有相同 的即可,不考虑顺序 |
是 |
match_phrase | 完全匹配 | match_phrase的分词结果必须在text字段分词中都包含 ,而且顺序必须相同,而且必须都是连续 的。 |
是 |
query_string | 完全匹配 | query_string中的分词结果至少有一个 在text字段的分词结果中,不考虑顺序 |
是 |