西安+美院+网站建设,要加强县门户网站的建设管理,网站推广教程,中国工厂网站Elasticsearch已升级#xff0c;新版Elasticsearch keyword博客参考下面这篇【Elasticsearch教程8】Mapping字段类型之keyword_elasticsearch的keyword_亚瑟弹琴的博客-CSDN博客
1 前言 本文基于ES7.6#xff0c;如果是之前版本#xff0c;是有区别的。 ES支持的字段类型很…Elasticsearch已升级新版Elasticsearch keyword博客参考下面这篇【Elasticsearch教程8】Mapping字段类型之keyword_elasticsearch的keyword_亚瑟弹琴的博客-CSDN博客
1 前言 本文基于ES7.6如果是之前版本是有区别的。 ES支持的字段类型很多但工作中常用的也就那些核心字段。 一开始学习ES时掌握好常用的类型不必要精通每一种如果工作中遇到了需要用到特殊类型再去研究。 学习一门技术要先广度后深度不能陷入”只见树木不见森林“。 2 核心类型 2.1 关键词keyword keyword类型通常存储结构性数据而不是毫无规律可言的文本信息。
2.1.1 适合用keyword的例子 场景 值 订单状态的枚举值 1未付款2已付款3申请退款4已退款 HTTP状态码 200400500404 手机号/邮箱/性别 对手机号没必要分词也不需要数学计算所以也不能设为数字类型 用户画像标签 学生IT男屌丝女孕妈社会中产 2.1.2 说明 ES把keyword类型的值当作词根存在倒排索引中不进行分词。 keyword适合存结构化数据比如name,age,性别,手机号,status(数据状态),tags(标签)HttpCode(404,200,500)等。 字段常用来精确查询过滤排序聚合时应设为keyword而不是数值型。 如果某个字段你经常用来做range查询, 你还是设置为数值型(integer,long),ES对数字的range有优化。 还可以把字段设为multi-field,这样又有keyword类型又有数值类型, 方便各个方式的使用。 最长支持32766个UTF-8类型的字符但放入倒排索引时只截取前一段字符串长度由ignore_above参数决定。 2.1.3 实验 1创建一个文档
PUT /pigg_user/_doc/1 { name: 冬哥, age: 32 } 2查询数据
GET /pigg_user/_doc/1/_source
#返回结果如下说明插入成功 { name : 冬哥, age : 32 } 1 2 3 4 5 6 7 3查询name冬哥的数据
GET /pigg_user/_search { query: { term: { name: 冬哥 } } }
#返回结果如下居然没有搜索到??? { ...省略其它信息... hits : { total : { value : 0, relation : eq }, max_score : null, hits : [ ] } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 4查看文档的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下面会讲 } } } } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 5分析原因 如果不设置mappingES默认把字符串设为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: 冬 } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 2.1.4 手动设置mapping #先删除之前创建的index DELETE pigg_user
#设置name为keywordage为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: 冬哥 } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 2.1.5 ignore_above是什么 首先随意往ES插一条数据
put my_index/_doc/1 { name: 李星云 } 1 2 3 4 查看ES自动生成的mappingname是text类型其下还有子类型keyword且ignore_above : 256
GET /my_index/_mapping
name定义如下 properties : { name : { type : text, fields : { keyword : { type : keyword, ignore_above : 256 } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 对于keyword类型 可设置ignore_above限定字符长度。超过 ignore_above 的字符会被存储但不会被倒排索引。比如ignore_above4”abc“”abcd“”abcde“都能存进ES但是不能根据”abcde“检索到数据。
【1】创建一个keyword类型的字段ignore_above4
PUT test_index { mappings: { _doc: { properties: { message: { type: keyword, ignore_above: 4 } } } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 【2】向索引插入3条数据
PUT /test_index/_doc/1 { message: abc }
PUT /test_index/_doc/2 { message: abcd }
PUT /test_index/_doc/3 { message: abcde } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 此时ES倒排索引是
词项 文档ID abc 1 abcd 2 【3】根据message进行terms聚合 GET /test_index/_search { size: 0, aggs: { term_message: { terms: { field: message, size: 10 } } } } 1 2 3 4 5 6 7 8 9 10 11 12 返回结果
{ took : 2, timed_out : false, _shards : { total : 5, successful : 5, skipped : 0, failed : 0 }, hits : { total : 3, max_score : 1.0, hits : [ { _index : test_index, _type : _doc, _id : 2, _score : 1.0, _source : { message : abcd } }, { _index : test_index, _type : _doc, _id : 1, _score : 1.0, _source : { message : abc } }, { _index : test_index, _type : _doc, _id : 3, _score : 1.0, _source : { message : abcde } } ] }, aggregations : { term_message : { doc_count_error_upper_bound : 0, sum_other_doc_count : 0, buckets : [#注意这分组里没有”abcde“ { key : abc, doc_count : 1 }, { key : abcd, doc_count : 1 } ] } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 【4】根据”abcde“进行term精确查询,结果为空
GET /test_index/_search { query: { term: { message: abcde } } }
然后结果 hits : { total : 0, max_score : null, hits : [ ] } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 通过上面结果能知道”abcde“已经存入ES也可以搜索出来但是不存在词项”abcde“不能根据”abcde“作为词项进行检索。 对于已存在的keyword字段其ignore_above子属性可以修改但只对新数据有效。 ———————————————— 版权声明本文为CSDN博主「亚瑟弹琴」的原创文章遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。 原文链接https://blog.csdn.net/winterking3/article/details/108254346