相信很多人都已经接触过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": "一条"
    }
  }

}

es检索不分词 elasticsearch 不分词_java


可以看到三个文档都被查询出来了

这里很好理解,match会分词去查,当查询 “一条” 时会分为 “一条” “一” “条” 三个词,只要一个文档中包含其中任意一个即可,

这里可能会有人不理解为什么会 分为 “一条” “一” “条” 这三个词

执行

POST _analyze
{
  "analyzer": "ik_max_word",
  "text": ["一条"]
}

返回结果为:

es检索不分词 elasticsearch 不分词_字段_02

接下来看 第二个查询语句

POST test_match/_search
{
  "query": {
    "match": {
      "name": "一条"
    }
  }
  
}

es检索不分词 elasticsearch 不分词_es检索不分词_03

但结果就只有一条,上面我们分析这个match, 它查询的时候会分词,查询 “一条” 时会分为 “一条” “一” “条” 三个词 很显然 我们 doc2 和 doc3 肯定是分别包含 “一” 和 “条” 的,那这里为什么没有查询出来?
很显然结果只有一个,那就是查询的时候没有分词, 等等? 不是说match查询的时候会分词的吗? 是的,但是如果这个字段本身是keyword类型的也就是不分词的情况下,那么match去查询的时候也不会进行分词。

那该怎么验证我上面说的?
我们可以通过Elasticsearch提供的profile来验证
第一个查询改为

POST test_match/_search
{
  "query": {
    "match": {
      "title": "一条"
    }
  }
  , "profile": "true"
}

es检索不分词 elasticsearch 不分词_Elastic_04

可以看到它将我们的match查询转成了 bool 查询并且有三个条件
我们分别来看下这三个条件

es检索不分词 elasticsearch 不分词_java_05

es检索不分词 elasticsearch 不分词_Elastic_06

es检索不分词 elasticsearch 不分词_tomcat_07

等价于

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"
}

es检索不分词 elasticsearch 不分词_字段_08

可以看到直接就被翻译成了 term查询
等价于

POST test_match/_search
{
  "query": {
      "term": {
         "name": {
            "value": "一条"
            }
       }
  }
}

现在我们知道match是怎样执行的了,如果查询的字段分词,那就将查询的条件也分词去查
如果查询的字段是不分词的,那么查询的时候就是不分词的了