相信很多人都已经接触过Elasticsearch了,而且查询的时候使用的最多的就是 match 查询
那么match 到底是怎么做的呢?
接下来用Elasticsearch的 profile 来分析match查询到底是个什么鬼?为什么有的时候会分词去查,有的时候又不会分词去查询。
我使用的是Elasticsearch7.6 (不同版本可能会稍有不同) 和Ik分词器
首先我们先创建索引
PUT test_match
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"title" :{
"type": "text"
, "analyzer": "ik_max_word"
}
}
},
"settings": {
"number_of_replicas": 0
}
}
新增数据
PUT test_match/_doc/1
{
"name": "一条",
"title": "一条"
}
PUT test_match/_doc/2
{
"name": "一",
"title": "一"
}
PUT test_match/_doc/3
{
"name": "条",
"title": "条"
}
name是不分词的字段,title是分词的,每条记录的name和title的值是一样的
执行以下查询语句
POST test_match/_search
{
"query": {
"match": {
"title": "一条"
}
}
}
可以看到三个文档都被查询出来了
这里很好理解,match会分词去查,当查询 “一条” 时会分为 “一条” “一” “条” 三个词,只要一个文档中包含其中任意一个即可,
这里可能会有人不理解为什么会 分为 “一条” “一” “条” 这三个词
执行
POST _analyze
{
"analyzer": "ik_max_word",
"text": ["一条"]
}
接下来看 第二个查询语句
POST test_match/_search
{
"query": {
"match": {
"name": "一条"
}
}
}
但结果就只有一条,上面我们分析这个match, 它查询的时候会分词,查询 “一条” 时会分为 “一条” “一” “条” 三个词 很显然 我们 doc2 和 doc3 肯定是分别包含 “一” 和 “条” 的,那这里为什么没有查询出来?
很显然结果只有一个,那就是查询的时候没有分词, 等等? 不是说match查询的时候会分词的吗? 是的,但是如果这个字段本身是keyword类型的也就是不分词的情况下,那么match去查询的时候也不会进行分词。
那该怎么验证我上面说的?
我们可以通过Elasticsearch提供的profile来验证
第一个查询改为
POST test_match/_search
{
"query": {
"match": {
"title": "一条"
}
}
, "profile": "true"
}
可以看到它将我们的match查询转成了 bool 查询并且有三个条件
我们分别来看下这三个条件
等价于
POST test_match/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"title": {
"value": "一条"
}
}
},
{
"term": {
"title": {
"value": "一"
}
}
},
{
"term": {
"title": {
"value": "条"
}
}
}
]
}
}
}
那么第二个查询呢?
POST test_match/_search
{
"query": {
"match": {
"name": "一条"
}
}
, "profile": "true"
}
可以看到直接就被翻译成了 term查询
等价于
POST test_match/_search
{
"query": {
"term": {
"name": {
"value": "一条"
}
}
}
}
现在我们知道match是怎样执行的了,如果查询的字段分词,那就将查询的条件也分词去查
如果查询的字段是不分词的,那么查询的时候就是不分词的了