再谈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区别

在讲解matchterm区别之前先来说明一下textkeyword的区别,简单一句话就是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": [
                        "测试一下"
                    ]
                }
            }
        ]

如果只查询测试是查不到的。

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": [
                        "中国科学院计算研究所"
                    ]
                }
            }
        ]

采用下面的请求分析一下中国科学院计算研究所被分成了哪些词:

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": [
                        "中国人民"
                    ]
                }
            }
        ]
    }
}

只有这一个查询条件可以成功,其他的都会失败。

4.match查询text字段

matchtext都支持分词,所以只要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": [
                        "中国科学院计算研究所"
                    ]
                }
            }
        ]
    }
}

可以看出,因为中国科学院计算研究所的分词结果包含中国,所以只使用中国就可以查询到。如果查询条件是加油中国中国必胜,只要是分词结果中含有中国的都可以查询出来。同样,对于其他的分词也是一样。

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": [
                        "中国人民"
                    ]
                }
            }
        ]
    }
}

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": [
                        "中国科学院计算研究所"
                    ]
                }
            }
        ]
    }
}

下面的查询也可以


{
	"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字段的分词结果中,不考虑顺序


你可能感兴趣的:(Elasticsearch)