在es的复杂查询中,比较常用的查询条件就是match和term了。那么他们有什么区别呢?

1. match和term的区别

  • match会进行分词,将分词后的field去倒排索引寻找文档;
  • term不会进行分词,将原始的field去倒排索引中寻找文档;

而文档在倒排索引中存储的是什么值呢?可以通过下面uri进行分析:

# 创建索引
PUT test_match

# 查看字段的分词后存储在倒排索引的值
GET test_match/_analyze
{
  "field": "{field}",
  "text": []
}

2. 实战分析

2.1 数据准备

# 创建索引
PUT test_match

# 创建映射关系
PUT test_match/_mapping
{
  "properties":{
    "text_name":{
      "type":"text"
    },
    "key_name":{
      "type":"keyword"
    }
  }
}

# 批量插入数据
POST _bulk
{"create":{"_index":"test_match","_type":"_doc"}}
{"text_name":"JAVA BOOK","key_name":"JAVA BOOK"}
{"create":{"_index":"test_match","_type":"_doc"}}
{"text_name":"ES BOOK","key_name":"ES BOOK"}
{"create":{"_index":"test_match","_type":"_doc"}}
{"text_name":"spring","key_name":"spring"}

2.2 倒排索引存储的值

  1. 若类型为text格式:

image.png

有上图可知,倒排索引存储的值实际上是esbook,而不是es book

**注意:**因为是默认被standard analyzer分词器分词,大写字母全部转为了小写字母,并存入了倒排索引以供搜索。term是确切查询, 所以传入的条件要和倒排索引保持一致。

  1. 若类型为keyword格式:

image.png

需要注意的是,倒排索引中存储的值为大写的ES BOOK

2.3 使用term查询text类型(不推荐)

使用term查询时,查询条件不会进行分词。但是text类型的数据,在倒排索引中实际存储的是分词的数据。
image.png

term条件的区分大小写,而实际上,text数据经过默认的standard analyzer分词器分词,大写字母全部转为了小写字母,并存入了倒排索引以供搜索。

image.png

image.png

故不推荐使用term去查询text类型。

2.4 term查询keyword等类型的数据

term去查询keyword的数据,均不会进行分词,但是需要注意大小写

image.png

2.4 match查询text类型

match查询text类型时,其本质的操作为or。

image.png

GET test_match/_search
{
  "query": {
    "match": {
      "text_name":"JAVA ES"
    }
  }
}

可等效为:

GET test_match/_search
{
  "query": {
    "match": {
      "text_name":{
        "query": "JAVA ES",
        "operator": "or"
      }
    }
  }
}

并且match匹配时,底层分词器会将条件转换为小写,故和text的倒排索引的大小写保持一致。即不区分大小写。

image.png

2.4 match的and操作

上文说到,match默认使用or的操作。那么如何替换为and操作?

GET test_match/_search
{
  "query": {
    "match": {
      "text_name":{
        "query": "JAVa book",
        "operator": "and"
      }
    }
  }
}

image.png

查询到的数据即包含JAVA 也要包含BOOK。

但是非精确匹配。

导入数据

POST test_match/_doc
{
  "text_name":"JAVA AND NET BOOK",
  "key_name":"net"
}

image.png

再次执行时,依旧可以查询到JAVA AND NET BOOK数据。

and操作,是要求倒排索引中即要包含java也需要包含book

2.5 match查询keyword类型

match查询keyword操作时,等效term

image.png

3. match的底层转换

当match查询text类型时,在底层将会被转换为term操作。

image.png

将被转换为:

GET test_match/_search
{
  "query": {
    "bool": {
      "should": [
        {"term": {
          "text_name": {
            "value": "java"
          }
        }},
        {
          "term": {
            "text_name": {
              "value": "book"
            }
          }
        }
      ]
    }
  }
}

image.png

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐