Elasticsearch教程(28) text和keyword区别 term和match区别 ik中文分词器使用

一、前言

最近啊,我发现有个老同志(其实指我自己)在工作中用ES也好几年了,从ES5.6一直用到ES7.9。

但是这个同志对text和keyword区别、term和match区别还是很模糊,反正能用工具把ES中数据查询出来,全当MySQL这样关系型数据库用了。

我感觉ES的版本升的比较快,但是升的都是高级功能和底层实现。像text和keyword、term和match这些基础中的基础还是没啥变化的。

如果用ES好几年了,连text和keyword、term和match这些都搞不明白,还有脸说自己会ES?啊?看我老亚瑟给你一刀,再一刀,大招落地+斩杀,祝你幸福。
在这里插入图片描述

二、之前相关的博客

之前我的博客关于match、term、text和keyword的讲解也不少,主要集中如下三篇。有兴趣的请选择食用。
Elasticsearch笔记(九) Query DSL 查询教程
Elasticsearch笔记(十) Mapping 字段类型 keyword text date numeric
Elasticsearch笔记(十一) ES term terms prefix 搜索 聚合查询 详细总结

三、造点测试数据

1. 创建一个index

下面创建一个index,它只有3个字段

字段说明类型分词器
title标题textES自带的标准分词器,适合英文
author作者keyword
content内容textik中文分词器,这里用 ik_smart

具体ik的安装和使用,网上优秀博客一大堆,这里我只给个官方链接吧
官方地址
下载地址

PUT pigg_blog
{
  "mappings": {
    "properties": {
      "title":{
        "type": "text",
        "analyzer": "standard"
      },
      "author":{
        "type": "keyword"
      },
      "content":{
        "type": "text",
        "analyzer": "ik_smart"
      }
    }
  }
}

2. 插入测试数据

PUT pigg_blog/_doc/1
{
  "title": "宝贝ABC",
  "author": "宝贝巴士",
  "content": "宝贝,宝贝ABC"
}

PUT pigg_blog/_doc/2
{
  "title": "小跳蛙宝宝",
  "author": ["彭钧", "李润"],
  "content": "小跳蛙宝宝"
}

四、做一份试卷

先做一份试卷,你可以先用笔记下你的答案,正确的答案在后面会给出。
每题你只需要写出返回的文档id。

第1题:title term "宝贝"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "宝贝"
      }
    }
  }
}

第2题:title term "宝宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "宝宝"
      }
    }
  }
}

第3题:title term "宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "宝"
      }
    }
  }
}

第4题:title term "ABC"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "ABC"
      }
    }
  }
}

第5题:title term "abc"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "abc"
      }
    }
  }
}

第6题:title match "宝贝"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "title": "宝贝"
    }
  }
}

第7题:title match "宝宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "title": "宝宝"
    }
  }
}

第8题:title match "ABC"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "title": "ABC"
    }
  }
}

第9题:content match "宝贝"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "content": "宝贝"
    }
  }
}

第10题:content match "宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "content": "宝"
    }
  }
}

第11题:author term "宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "author": {
        "value": "宝"
      }
    }
  }
}

第12题:author term "彭钧"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "author": {
        "value": "彭钧"
      }
    }
  }
}

第13题:author match"彭钧"的结果?

GET pigg_blog/_search
{
  "query": {
      "match": {
        "author": "彭钧"
      }
    }
  }
}

五、分析title字段

看正确答案前,先看下分词器对文本的分析。

POST pigg_blog/_analyze
{
  "analyzer": "standard",
  "text": ["宝贝ABC"]
}

结果如下:

{
  "tokens" : [
    {
      "token" : "宝",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "贝",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "abc",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position" : 2
    }
  ]
}
POST pigg_blog/_analyze
{
  "analyzer": "standard",
  "text": ["小跳蛙宝宝"]
}

结果如下:

{
  "tokens" : [
    {
      "token" : "小",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "<IDEOGRAPHIC>",
      "position" : 0
    },
    {
      "token" : "跳",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "<IDEOGRAPHIC>",
      "position" : 1
    },
    {
      "token" : "蛙",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "<IDEOGRAPHIC>",
      "position" : 2
    },
    {
      "token" : "宝",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "<IDEOGRAPHIC>",
      "position" : 3
    },
    {
      "token" : "宝",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "<IDEOGRAPHIC>",
      "position" : 4
    }
  ]
}

六、分析content字段

POST pigg_blog/_analyze
{
  "analyzer": "ik_smart",
  "text": ["宝贝,宝贝ABC"]
}

结果如下:

{
  "tokens" : [
    {
      "token" : "宝贝",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "宝贝",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "abc",
      "start_offset" : 5,
      "end_offset" : 8,
      "type" : "ENGLISH",
      "position" : 2
    }
  ]
}
POST pigg_blog/_analyze
{
  "analyzer": "ik_smart",
  "text": ["小跳蛙宝宝"]
}

结果如下:

{
  "tokens" : [
    {
      "token" : "小跳",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "蛙",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "宝宝",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 2
    }
  ]
}

七、答案

不知道看过上面的解析,你对你的答案还确定几题呢?

第1题:title term "宝贝"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "宝贝"
      }
    }
  }
}

答案:空

第2题:title term "宝宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "宝宝"
      }
    }
  }
}

答案:空

第3题:title term "宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "宝"
      }
    }
  }
}

答案:1和2都返回

第4题:title term "ABC"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "ABC"
      }
    }
  }
}

答案:空

第5题:title term "abc"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "title": {
        "value": "abc"
      }
    }
  }
}

答案:返回文档1

第6题:title match "宝贝"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "title": "宝贝"
    }
  }
}

答案:1和2都返回

第7题:title match "宝宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "title": "宝宝"
    }
  }
}

答案:1和2都返回

第8题:title match "ABC"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "title": "ABC"
    }
  }
}

答案:返回文档1

第9题:content match "宝贝"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "content": "宝贝"
    }
  }
}

答案:返回文档1

第10题:content match "宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "match": {
      "content": "宝"
    }
  }
}

答案:空

第11题:author term "宝"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "author": {
        "value": "宝"
      }
    }
  }
}

答案:空

第12题:author term "彭钧"的结果?

GET pigg_blog/_search
{
  "query": {
    "term": {
      "author": {
        "value": "彭钧"
      }
    }
  }
}

答案:返回文档2

第13题:author match"彭钧"的结果?

GET pigg_blog/_search
{
  "query": {
      "match": {
        "author": "彭钧"
      }
    }
  }
}

答案:返回文档2

八、添加自定义的词项

在上面发现ik分词器把”小跳蛙“分析成"小跳"和"蛙"这2个词,这个显然是不符合我预期的,这个时候就需要我们自己来添加自定义词项。

1. 添加自定义字典文件

在es的plugins\ik\config目录下,添加一个文本文件,命名为ext.dic,然后输入自己的词,最后一行也回车。
在这里插入图片描述

2. 配置自定义字典文件

在这里插入图片描述
然后重启es服务就可以了。

3. 测试

POST pigg_blog/_analyze
{
  "analyzer": "ik_smart",
  "text": ["小跳蛙宝宝"]
}

结果如下:

{
  "tokens" : [
    {
      "token" : "小跳蛙",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "宝宝",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 1
    }
  ]
}

这个时候你发现上面的只有"小跳蛙",没有"跳蛙",如果需要"跳蛙",可以把分析器设置为"ik_max_word",它会将词分析出最大数量的词项。

POST pigg_blog/_analyze
{
  "analyzer": "ik_max_word",
  "text": ["小跳蛙宝宝"]
}

结果如下:

{
  "tokens" : [
    {
      "token" : "小跳蛙",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "小跳",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "跳蛙",
      "start_offset" : 1,
      "end_offset" : 3,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "宝宝",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 3
    }
  ]
}

九、token_count

token_count是一个字段类型,用于统计分词后词项的个数,在特殊场景下还是比较有用的。
删除原来index,重新创建索引的mapping,并插入原来的数据。

PUT pigg_blog
{
  "mappings": {
    "properties": {
      "title":{
        "type": "text",
        "analyzer": "standard"
      },
      "author":{
        "type": "keyword"
      },
      "content":{
        "type": "text",
        "analyzer": "ik_smart",
        "fields": {
          "length": {
            "type": "token_count",
            "analyzer": "ik_smart"
          }
        }
      }
    }
  }
}
GET pigg_blog/_search
{
  "query": {
    "term": {
      "content.length": {
        "value": 3
      }
    }
  }
}

返回结果如下:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "pigg_blog",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "title" : "宝贝ABC",
          "author" : "宝贝巴士",
          "content" : "宝贝,宝贝ABC"
        }
      }
    ]
  }
}

十、结语

感觉做个IT打工仔,要学的东西很多,es,flink,spring cloud,vue,每次看到好的教程都是点赞,收藏,退出,一气呵成。还是慢慢学吧,积累一点算一点。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑟 王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值