0


【Elasticsearch教程8】Mapping字段类型之keyword

Elasticsearch Mapping字段类型之keyword

一、前言

ES的

keyword

类型家族有3种:

  1. keyword,用于结构化内容,如ID、邮箱、邮编、手机号、主机名、状态码或标记
  2. constant_keyword,某个字段为constant_keyword类型,则该index中,所有文档的该字段的值必须一致
  3. wildcard,存非机构化数据,且值的内容大,相似性低的数据,如HTTP请求体,Log日志这些让人阅读性差的数据。

其中第1个

keyword

类型是最常用的类型,后面2个类型出现的比较晚,使用的场景也比较少。

二、keyword

2.1 keyword适用场景

keyword

类型通常存储结构化数据,对

keyword

类型不能进行

match

查询,适合用

keyword

的例子:
场景值订单状态1:未付款;2:已付款;3:申请退款;4:已退款HTTP状态码200,400,500,404ID/手机号/邮箱/性别对手机号没必要分词,也不需要数学计算,所以也不能设为数字类型用户画像标签学生,IT男,腐女,宝妈

  • ES把keyword类型的值作为一整体存在倒排索引中,不进行分词。
  • keyword适合存结构化数据,如性别、手机号、数据状态、标签HttpCode(404,200,500)等。
  • 字段常用来精确查询、过滤、排序、聚合时,应设为keyword,而不是数值型。
  • 如果某个字段你经常用来做range查询, 你还是设置为数值型(integer,long),ES对数字的range有优化。
  • 还可以把字段设为multi-field,这样又有keyword类型又有数值类型,方便多种方式的使用。
  • 最长支持32766个UTF-8类型的字符,但放入倒排索引时,只截取前一段字符串,长度由ignore_above参数决定,默认"ignore_above" : 256

2.2 keyword实验

(1)创建一个文档

PUT/pigg_user/_doc/1{"name":"冬哥","age":32}

(2)查询name="冬哥"的数据,用

term

name

字段上查询,是查询不到文档的

这条语句是查询不到的
GET/pigg_user/_search
{"query":{"term":{"name":"冬哥"}}}

(3)查看文档的mapping
要想探知没有搜到的原因,得先看排查文档的mapping,发现name是

text类型

,其下面有一个

keyword子类型

GET/pigg_user/_mapping

#返回如下
{"pigg_user":{"mappings":{"properties":{"age":{"type":"long"},"name":{"type":"text","fields":{"keyword":{          #这行的keyword是字段名,全称是name.keyword
              "type":"keyword",  #这行的keyword是指类型
              "ignore_above":256 #这里的ignore_above下面会讲
            }}}}}}}

(4)分析原因
如果不设置mapping,ES默认把字符串设为

text类型

,并包含一个

keyword子类型


name是

text类型

,“冬哥”这个词已经被拆成“冬”和“哥”这2个词。
所以上面用term来匹配“冬哥”时,查询不到数据。
简单理解:

  • “name”这个字段按照“冬”和“哥”2个词存的,根据“冬”或者“哥”都能term查询到文档。
  • “name.keyword”这个字段存储的是“冬哥”这完整字符串。
#根据name匹配“冬”,可以查询到文档
GET/pigg_user/_search
{"query":{"term":{"name":"冬"}}}

#根据name.keyword匹配"冬哥",可以查询到文档
GET/pigg_user/_search
{"query":{"term":{"name.keyword":"冬哥"}}}

#根据name.keyword匹配"冬",查询不到文档
GET/pigg_user/_search
{"query":{"term":{"name.keyword":"冬"}}}

2.3 手动设置keyword类型

#先删除之前创建的index
DELETE pigg_user

#设置name为keyword,age为short。
PUT pigg_user
{"mappings":{"properties":{"name":{"type":"keyword"},"age":{"type":"short"}}}}

#新增一个文档
PUT/pigg_user/_doc/1{"name":"冬哥","age":32}

#根据name精确匹配,可以查到数据
GET/pigg_user/_search
{"query":{"term":{"name":"冬哥"}}}

三、constant_keyword类型

constant_keyword

 keyword

字段的特例,用于索引中所有文档具有相同值的情况。

PUT logs-debug
{"mappings":{"properties":{"@timestamp":{"type":"date"},"message":{"type":"text"},"level":{"type":"constant_keyword", #指明level这个字段是constant_keyword类型
        "value":"debug"               #且所有文档的level字段的值都是debug
      }}}}
constant_keyword

支持与

 keyword

字段相同的查询和聚合,而且

constant_keyword

的效率更高,因为ES利用所有文档的的某个

constant_keyword

字段的值必须相同的这一事实,进行了针对性优化。

允许提交

没有字段值

值等于映射中配置的值

的文档。 以下两个索引请求是等效的:

POST logs-debug/_doc
{"date":"2019-12-12","message":"Starting up Elasticsearch","level":"debug"}POST logs-debug/_doc
{"date":"2019-12-12","message":"Starting up Elasticsearch"}

如果把

level

设置成

非debug

的值,比如

error

,则会返回错误

POST logs-debug/_doc
{"date":"2019-12-12","message":"Starting up Elasticsearch","level":"error"}

返回如下错误提示:

"caused_by":{"type":"illegal_argument_exception","reason":"[constant_keyword] field [level] only accepts values that are equal to the value defined in the mappings [debug], but got [error]"}
constant_keyword

类型使用的场景确实非常少见,所以用的很少。

四、wildcard类型

当你要在某个非结构化数据上进行

wildcard

regexp

查询的时候,

wildcard类型

就比较合适了。

  • 这种非结构化数据的内容一般是机器产生的(machine-generated),它们的可阅读比较低,不适合我们人阅读,比如日志message或者HTTP的请求体。
PUT my-index-000001{"mappings":{"properties":{"my_wildcard":{"type":"wildcard"}}}}PUT my-index-000001/_doc/1{"my_wildcard":"This string can be quite lengthy"}GET my-index-000001/_search
{"query":{"wildcard":{"my_wildcard":{"value":"*quite*lengthy"}}}}

本文转载自: https://blog.csdn.net/winterking3/article/details/126548603
版权归原作者 瑟王 所有, 如有侵权,请联系我们删除。

“【Elasticsearch教程8】Mapping字段类型之keyword”的评论:

还没有评论