Elasticsearch Mapping字段类型之text 以及term、match和analyzer

  • 一、text场景
  • 二、`term`查询
  • 三、`match`查询
    • 1. `亚瑟王`如何存储?
    • 2. `鼓励王`如何搜索?
    • 3. match的参数
      • 3.1 operator
      • 3.1 minimum_should_match
    • 4. 匹配短语 match_phrase
  • 四、分析器 analyzer

一、text场景

text类型是适合全文搜索的场景,ES会将文本分析成多个词并索引。

  • text类型适合存放易阅读的(human-readable)非结构化文本,比如邮件内容、评论、商品介绍等
  • 对于阅读性差的文本,如系统日志、Http请求体这些machine-generated数据,可以用wildcard类型
  • text类型不适合排序聚合(虽然可以实现,但是不建议)
  • 如果要进行排序聚合,建议使用keyword类型
  • 所以可以给text类型添加keyword子类型token_count子类型,各司其职
PUT pigg_test_text
{"mappings": {"properties": {"name": {            # 姓名 name"type": "text","fields": {"keyword": {     # 子字段 name.keyword"type": "keyword","ignore_above" : 256},"length": {       # 子字段 name.length"type": "token_count","analyzer": "standard"}}},"tag": {             # 标签 tag"type": "keyword"},"word": {              # 台词 word"type": "text"}}}
}

二、term查询

  • term判断某个字段是否包含某个确定的值。一般用在keywordintegerdatetoken_countip等类型上
  • 避免在text类型上用term,在text上应该用matchmatch_phrase来全文搜索

先插入两条《王者荣耀》里英雄的数据:

PUT pigg_test_text/_doc/1
{"name": "亚瑟王","tag": ["对抗路", "打野"],"word": ["王者背负,王者审判,王者不可阻挡"]
}PUT pigg_test_text/_doc/2
{"name": "关羽","tag": ["对抗路", "辅助"],"word": ["把眼光从二爷的绿帽子上移开","聪明的人就应该与我的大刀保持安全距离"]
}

(1)查询name亚瑟王的人

  • name.keyword上用term查询,返回id=1的文档
  • 注意:term不是等于的意思,是包含的意思
GET pigg_test_text/_search
{"query": {"term": {"name.keyword": "亚瑟王"}}
}

(2)查询可走对抗路的人

  • tag上用term查询,返回id=1和2的文档,因为他们的tag包含对抗路
GET pigg_test_text/_search
{"query": {"term": {"tag": "对抗路" }}
}

(3)查询是打野或辅助的人

  • tag上用terms查询(注意多了个s),返回id=1和2的文档
  • 因为terms查询只要包含数组中任意一个就算匹配

GET pigg_test_text/_search
{"query": {"terms": {"tag": ["打野", "辅助"]}}
}

(4)查询name是3个字的人

  • token_count类型的name.length上做精确匹配,返回亚瑟王的文档
GET pigg_test_text/_search
{"query": {"term": {"name.length": 3}}
}

三、match查询

虽然上面亚瑟王关羽这2个文档内容是中文,而且我也没有配置ik中文分词器,但是这不影响我们的学习,我们只要知道中文被默认的standard analyzer切分成独立的汉字就行了。

match全文搜索鼓励王,返回亚瑟王文档,因为匹配中了这个汉字。

GET pigg_test_text/_search
{"query": {"match": {"name": "鼓励王"}}
}

对上面这条语句不是很理解的话,我从亚瑟王如何存储?和鼓励王如何搜索?这2个角度的问题来解释。

1. 亚瑟王如何存储?

  • _termvectors可以帮助我们查看文本是如何分割成词条的
  • 国内博客对这里的term的翻译有多种:词条、词根、词项等等,我们不必纠结,知道意思就行
查询id=1的文档的name字段的词条向量GET pigg_test_text/_doc/1/_termvectors?fields=name

返回这3个词,说明在倒排索引里有类似如下的关系:

文档ID
1
1
1

2. 鼓励王如何搜索?

第1种方法:使用_analyze分析standard这个分析器是如何分割搜索关键字的。这里得指定name字段上search-timeanalyzer,即search_analyzer

GET /_analyze
{"analyzer" : "standard","text" : "鼓励王"
}返回"鼓"、"励"、"王"这3个token

第2种方法:使用_validate验证语句是否合法,其参数explain(默认为true)会解释语句的执行计划

GET pigg_test_text/_validate/query?explain
{"query": {"match": {"name": "鼓励王"}}
}

返回结果如下,name:鼓 name:励 name:王说明是把鼓励王拆成3个汉字分别到name字段上做匹配的。

"valid" : true,
"explanations" : [{"index" : "pigg_test_text","valid" : true,"explanation" : "name:鼓 name:励 name:王"}
]

第3种方法:使用_explain查询鼓励王是如何匹配到id=1的文档的?这种方式的前提是我们已经知道关键词匹配到哪个文档了,想知道匹配的原因。

解释`鼓励王`为何在name字段上匹配到id=1的文档
GET /pigg_test_text/_explain/1
{"query" : {"match" : { "name" : "鼓励王" }}
}

返回内容比较长,也比较复杂,因为涉及到打分机制,这里就贴一个重点:

"description" : "weight(name:王 in 0) [PerFieldSimilarity], result of:",

说明是这个字让鼓励王name字段上匹配到id=1的文档的。

3. match的参数

match还有2个比较重要的参:operatorminimum_should_match,他们可以控制match查询的行为。

3.1 operator

上面match查询鼓励王的语句,其实可以写成如下:

GET pigg_test_text/_search
{"query": {"match": {"name": {"query": "鼓励王","operator": "or"}}}
}
  • 这个operater的默认值就是or,就是只要匹配到任意一个词,就算匹配成功。
  • 如果要"鼓励王"这三个词全部匹配,可以设置 "operator": "and"
GET pigg_test_text/_validate/query?explain=true
{"query": {"match": {"name": {"query": "鼓励王","operator": "and"}}}
}返回如下:说明这3个字都得匹配
"explanations" : [{"index" : "pigg_test_text","valid" : true,"explanation" : "+name:鼓 +name:励 +name:王"}
]

3.1 minimum_should_match

  • minimum_should_match可以设置匹配的最小词数,不要与operator一起使用,意思会冲突。
  • 它可以赋值正数、负数、百分比等,但是我们常用的是设置一个正数,即指定最小匹配的词数。
指定要至少匹配成功2个字,才算文档匹配成功
GET pigg_test_text/_search
{"query": {"match": {"name": {"query": "鼓励王","minimum_should_match": "2"}}}
}

4. 匹配短语 match_phrase

match_phrase短语查询,这个会将“绿帽子”作为一个短语整体去匹配,而不会拆成3个字

该语句返回关羽这个文档,因为他的台词包含"绿帽子"
GET pigg_test_text/_search
{"query": {"match_phrase": {"word": "绿帽子"}}
}

查询语句的执行计划:

GET pigg_test_text/_validate/query?explain
{"query": {"match_phrase": {"word": "绿帽子"}}
}返回如下:
"explanations" : [{"index" : "pigg_test_text","valid" : true,"explanation" : "word:\"绿 帽 子\""}
]

四、分析器 analyzer

text类型最重要的参数就是analyzer(分析器),它决定在index-time(创建或更新文档)和search-time(搜索文档)如何对文本进行分词。

  • analyzer:只配置了analyzer时,在index-timesearch-time时,都使用analyzer配置的分析器
  • search_analyzer:配置了search_analyzer时,在search-time时,使用search_analyzer配置的分析器

standard 分析器是text类型的默认分析器,它按照词边界对文本进行分割(如英语按照空格,中文切成独立汉字)。它删除了大多数标点符号和停止词并进行小写。standard 分析器对英语这样的西方语音是大多适用的。

分析器(analyzer)的配置包含3个重要部分,依次是character filterstokenizertoken filters
每当一个文档被 ingest 节点纳入,它需要经历如下的步骤,才能最终把文档写入到ES数据库中

英文 中文 analyzer配置项 个数 说明
character filters 字符过滤器 char_filter 0~n个 剥离html标签,转换特殊字符如&and
tokenizer 分词器 tokenizer 1个 把文本按一定规则分割成一个个词token,比如常见的standardwhitespace
token filters 词过滤器 filter 0~n个 对上一步产生的token进行规范化。
比如转小写、删除或新增术语、同义词转换等。

举例:tokenizersimple_pattern_split,配置按照下划线_来分割文本。

PUT my-index-000001
{"settings": {"analysis": {"analyzer": {"my_analyzer": {"tokenizer": "my_tokenizer"}},"tokenizer": {"my_tokenizer": {"type": "simple_pattern_split","pattern": "_"}}}}
}POST my-index-000001/_analyze
{"analyzer": "my_analyzer","text": "亚瑟王__鼓励王_可丽王"
}

按照下划线_切分后的词就是["亚瑟王", "鼓励王", "可丽王"]

  • 其实我们工作中也不用配置很多,这里了解下就行,不用深究每一个选项
  • 因为ES提供了很多开箱即用的内置analyzer,我们可根据场景来选择
  • 对于中文的分词,出名的有IK分词器,拼音分词器,可以参考我之前写的

IK分词器 ik_max_word、ik_smart
Pinyin拼音分词器
ik中文分词器+pinyin拼音分词器+同义词

【Elasticsearch教程18】Mapping字段类型之text 以及term、match和analyzer相关推荐

  1. ElasticSearch教程——创建索引、类型、文档

    ElasticSearch汇总请查看:ElasticSearch教程--汇总篇 介绍 索引是ElasticSearch存放数据的地方,可以理解为关系型数据库中的一个数据库.事实上,我们的数据被存储和索 ...

  2. ES篇:ElasticSearch教程——创建索引、类型、文档

    ES知识汇总:https://blog.csdn.net/gwd1154978352/article/details/82781731 介绍 索引是ElasticSearch存放数据的地方,可以理解为 ...

  3. ElasticSearch:文档字段类型及存储

    文章目录 1.文档字段存储 2.字段类型 2.1.字段的核心类型 2.2.衍生及多值类型 1.文档字段存储 文档字段指的是一个文档中存储的单元,比如以下文档中的username.age.favor就是 ...

  4. elasticsearch 关联查询_Elasticsearch字段类型之Range经典应用场景

    序言 Elasticsearch产品功能越来越强大,字段类型支持很多种,部分类型还引入了专用的算法.一个客户企业选中Elastic作为搜索中台,居然是看中了Elastic的Range字段类型,下面就围 ...

  5. 记一次ElasticSearch 更改 mapping 字段类型的过程

    我的个人博客:逐步前行STEP 首先,es不支持直接更改mappinng,所以,更改 mapping 实质上是重建索引. 操作步骤如下: 1.为当前这个索引old_index设置一个别名my_inde ...

  6. sequelize 设置mysql字段类型,text字符长度太小可采用longText

    从sequelize导出数据类型 const { DataTypes } = require('sequelize') 写法,此参数不传默认为text DataTypes.TEXT('long') 字 ...

  7. es 修改 mapping 字段类型

    一.原索引 PUT my_index {"mappings": {"_doc": {"properties": {"create_ ...

  8. vb.net 教程 1-8 日期时间类型1

    版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的. vb.net中日期时间函数使用DateTime,vb6中用的是Date,vb.net中也可以将日 ...

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

    text和keyword区别 term和match区别 ik中文分词器使用 一.前言 二.之前相关的博客 三.造点测试数据 1. 创建一个index 2. 插入测试数据 四.做一份试卷 第1题:tit ...

最新文章

  1. linux批处理mysql数据库_使用批处理对MySQL进行数据批量操作
  2. Handler消息传递机制
  3. 物联网实验4 alljoyn物联网实验之手机局域网控制设备
  4. 《潜意识:控制你行为的秘密》摘录
  5. java函数参数 省略号_[转] java使用省略号代替多参数.pdf
  6. WCF中的REST是什么
  7. 关于android输入框被键盘遮挡的问题
  8. 勉强算是面经——1.诺瓦科技
  9. 卡巴斯基的离线更新以及病毒库备份
  10. Win10下 QT的安装配置 (亲测可用)
  11. 读书笔记_《深度学习与计算机视觉》.叶韵 编著.田疆 西门子高级研究员 作序.机械工业出版社
  12. C语言面试题---函数(一)
  13. 「面试必背」TCP,UDP,Socket,Http网络编程面试题(快收藏)
  14. 伯朗特机器人编程语言_机器人十大流行编程语言
  15. LINUX下截图快捷方式
  16. 区块链中的哈希到底是什么?
  17. 计算机内存加速,电脑内存使用率过高怎么加速
  18. java-IOC(控制反转) 理论推导
  19. Mac终端自动补全及常用命令
  20. Win11如何自动清理垃圾?Win11自动删除文件设置方法

热门文章

  1. Alexnet LRN层和conv2局部连接
  2. 教育立志篇---一位台湾校长震动所有中国人的演讲---我现在学习还不晚
  3. Python的招牌菜xmlrpc
  4. 用python脚本查看电脑内存、CPU使用情况
  5. POJ 3270-Cow SortingA(Polya定理-交换次数)
  6. C语言中将二维数组作为函数参数来传递
  7. 如何理解信息隐蔽和局部化?
  8. js逆向播放量增加,增加视频热度,uuid,sid,buvid3,aid,b_lsid, b_nut 还原实现过程
  9. 怎么屏蔽还有照片_有一种尴尬叫:在朋友圈发照片,忘了屏蔽父母,老妈的回应亮了…...
  10. whoami: cannot find name for user ID xxxx