ElasticSearch全文搜索引擎之term和match的区别

目录

一、简介

二、term精确匹配

三、match模糊匹配

三、总结


一、简介

在elasticsearch中,查询主要使用到两个:term和match,本篇文章将总结一下两者的区别。

  • term:代表完全匹配,也就是精确查询,搜索前不会再对搜索词进行分词解析,直接对搜索词进行查找;
  • match:代表模糊匹配,搜索前会对搜索词进行分词解析,然后按搜索词匹配查找;

一般模糊查找的时候,多用match,而精确查找时可以使用term。

二、term精确匹配

term查询是直接通过倒排索引指定的词条进行查找的,所以,很显然,term查询效率肯定比match要高。

首先创建一个索引member,并插入几条测试数据,相关命令如下:

PUT /member/info/1
{
  "name": "张三",
  "age": 20
}

PUT /member/info/2
{
  "name": "张无忌",
  "age": 50
}

PUT /member/info/3
{
  "name": "李四",
  "age": 30
}

插入完成,观察索引里面的数据,如下图所示:

  • 查询name中精确匹配"张"的数据
GET /member/info/_search
{
  "query": {
    "term": {
      "name": "张"
    }
  }
}

由上图可见,两条数据都能查询出来,只要name里包含"张"关键字的数据都查出来了 。

如果我们只想精确匹配"张三"这个词,来看看下面的例子。

  • 查询name中精确匹配"张三"的数据
GET /member/info/_search
{
  "query": {
    "term": {
      "name": "张三"
    }
  }
}

我们发现,查询出来显示无数据,从概念上看,term属于精确匹配,只能查单个词。

如果我们想通过term匹配多个词的话,可以使用terms来实现:

GET /member/info/_search
{
  "query": {
    "terms": {
      "name": ["张","三"]
    }
  }
}

 可以看到,两条数据都成功返回,因为terms里的[ ] 多个搜索词之间是or(或者)关系,只要满足其中一个词即可

如果我们想要同时满足两个词精确匹配的话,就得使用bool的must来做,如下:

GET /member/info/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "name": "张"
          }
        },
        {
          "term": {
            "name": "三"
          }
        }
      ]
    }
  }
}

可以看到,此时只会返回一条满足条件的记录。

由于前面我们创建索引库member时并没有指定字段的类型,都是es默认生成的类型。

可以看到,默认生成的name字段是text类型

下面我们看看是如何进行分词处理的?

GET member/_analyze
{
  "text" : "张三"
}

 

分析出来的为"张"和""的两个词,而term只能完完整整的匹配上面的词,不做任何改变的匹配。

扩展: 两种数据类型:text和keyword

  • text:查询时会进行分词解析;
  • keyword:keyword类型的词不会被分词器进行解析,直接作为整体进行查询;

下面我们通过简单的示例说明一下text和keyword的区别。我们先创建一个test索引库:

PUT /test
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "desc": {
        "type": "keyword"
      }
    }
  }
}

下面我们插入几条测试数据:

PUT /test/_doc/1
{
  "name":"马士兵java name",
  "desc": "马士兵java desc"
}

PUT /test/_doc/2
{
  "name":"马士兵java name",
  "desc": "马士兵java desc2"
}

 

查看test索引库信息,可以看到我们指定的mappings,如下图:

  • 通过keyword类型的分词器进行解析
GET _analyze
{
  "analyzer": "keyword",
  "text":"马士兵java name"
}

 可以看到,使用keyword类型分词器时,搜索关键字并不会被分词器进行解析,直接作为一个整体词。

  • 通过standard类型的分词器进行解析
GET _analyze
{
  "analyzer": "standard",
  "text":"马士兵java name"
}

 可以看到,text类型的话搜索关键字将会被拆分为一个一个词,而前面的keyword类型的话不会被拆分,会当做一个整体。 

  • 查询name字段中含有"马"的记录
GET test/_search
{
  "query": {
    "term": {
      "name": "马"
    }
  }
}

可以看到,因为name字段是text类型,查询时候会被分词器分析,所以两条记录都成功查询出来。 

  • 查询desc字段中含有"马士兵java desc"的记录
GET test/_search
{
  "query": {
    "term": {
      "desc": "马士兵java desc"
    }
  }
}

可以看到,只返回一条记录,原因是desc字段是keyword类型,查询时候不会被分词器进行解析,作为一个整体查询。 

keyword类型的字段不会被分词器解析,text类型的字段会被分词拆分后才进行查询。

三、match模糊匹配

  • 查询姓名中匹配含"张三"这个词的数据
GET member/info/_search
{
  "query": {
    "match": {
      "name": "张三"
    }
  }
}

通过上图,我们可以看到两条记录都被查询出来的,因为match进行搜索的时候,会先进行分词拆分,拆完后,再来匹配。

"张三"被拆分解析为"张"和"三"两个词,所以只要name字段中包含"张"或者"三"的数据都能够匹配上。

如果想 "张"和"三"同时匹配到的话,那么可以使用 match_phrase,来看下面的例子:

match_phrase 称为短语搜索,要求所有的分词必须同时出现在文档中,同时位置必须紧邻一致。

可以看到,此时只会匹配出一条满足条件的记录。

三、总结

本文主要介绍了es中常用的两种查询方式:term和match。

  • term:代表完全匹配,也就是精确查询,搜索前不会再对搜索词进行分词解析,直接对搜索词进行查找;
  • match:代表模糊匹配,搜索前会对搜索词进行分词解析,然后按分词匹配查找;
  • term主要用于精确搜索,match则主要用于模糊搜索;
  • term精确搜索相较match模糊查询而言,效率较高;

同时总结了两种数据类型:text和keyword。

  • text:查询时会进行分词解析;
  • keyword:keyword类型的词不会被分词器进行解析,直接作为整体进行查询;

由于笔者水平有限,如文中有不对之处,还望指正,相互学习,一起进步!

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付 19.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值