深究|Elasticsearch单字段支持的最大字符数?

在业务系统中,遇到过两个问题:

问题1:设置为keyword类型的字段,插入很长的大段内容后,报字符超出异常,无法插入。 问题2:检索超过ignore_above设定长度的字段后,无法返回结果。

思考:Elasticsearch单字段支持的最大字符数?

本文是基于设置ignore_above之后引申的问题展开讨论与思考。

01

ignore_above的作用?

ES中用于设置超过设定字符后,不被索引或者存储。

Strings longer than the ignore_above setting will not be indexed or stored.

02

ignore_above用法

PUT ali_test
{
  "mappings": {
    "ali_type": {
        "properties": {
               "url": {
              "type":"keyword",
               "ignore_above":256
            },
               "url_long": {
              "type":"keyword"
            },
             "url_long_long": {
              "type":"keyword",
               "ignore_above":32766
            }
        }
    }
  }
}

03

当字符超过给定长度后,能否存入?

验证表名,对于以上mapping中设置的url,url_long,url_long_long3个字段。超过256字符的url,都可以存入。

3.1 keyword类型,普通长度验证

插入url长度为:1705个字符,如下所示:

post ali_test/ali_type/1
{
  "url" : "1705个字符的url"
}

url参考地址:http://t.cn/zH6FHG7

检索:

GET ali_test/ali_type/_search
{
  "query": {
    "term": {
"url" : "1705个字符的url"
}
}
}

返回结果:

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

结论:

1705个字符,url、url_long、url_long_long都可以存入,可以通过head插件查看结果。

但是url term检索无法检索返回结果,原因: url字段设置了"ignore_above":256,导致超出256个字符后不被索引。

3.2 对于keyword类型,临界长度验证

post 32767个字符的文档,报错如下:

{
    "error":{
        "root_cause":[
 {
                "type":"illegal_argument_exception",
                "reason":"Document contains at least one immense term in field="url_long" (whose UTF8 encoding is longer than the max length 32766), all of which were skipped.  Please correct the analyzer to not produce such terms.  The prefix of the first immense term is: '[104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 103, 111, 111, 103, 108, 101, 46, 99, 111, 109, 47, 115, 101, 97, 114, 99, 104, 63, 104]...', original message: bytes can be at most 32766 in length; got 32767"
            }
        ],
        "caused_by":{
            "type":"max_bytes_length_exceeded_exception",
            "reason":"max_bytes_length_exceeded_exception: bytes can be at most 32766 in length; got 32767"
        }
    },
    "status":400
}

post 32766个字符后,能提交成功,返回结果如下:

{
  "_index": "ali_test",
  "_type": "ali_type",
  "_id": "2000",
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "created": true
}

结论:keyword类型的最大支持的长度为——32766个UTF-8类型的字符。

也就是说term精确匹配的最大支持的长度为32766个UTF-8个字符。

04

text类型和keyword类型的存储字符数区别?

text类型:支持分词、全文检索,不支持聚合、排序操作。适合大字段存储,如:文章详情、content字段等;

keyword类型:支持精确匹配,支持聚合、排序操作。适合精准字段匹配,如:url、name、title等字段。

一般情况,text和keyword共存,设置mapping如下:

{
  "mappings": {
    "ali_type": {
        "properties": {
            "title_v1": {
                 "analyzer":"ik_max_word",
                    "type":"text",
                 "term_vector" : "with_positions_offsets",
                    "fields":{
                        "keyword":{
                            "ignore_above":256,
                            "type":"keyword"
                        }
                    }
            }
        }
    }
  }
}

05

小结

1)ES5.X版本以后,keyword支持的最大长度为32766个UTF-8字符,text对字符长度没有限制。

2)设置ignore_above后,超过给定长度后的数据将不被索引,无法通过term精确匹配检索返回结果。

参考:

http://t.cn/ROXyGes

原文发布于微信公众号 - 铭毅天下(gh_0475cf887cf7)

原文发表时间:2017-10-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏偏前端工程师的驿站

Velocity魔法堂系列二:VTL语法详解

一、前言                               Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页...

2185
来自专栏Python研发

Memcached·Redis缓存的基本操作

Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、...

1504
来自专栏Felix的技术分享

JVM的简单实现

1637
来自专栏linux系统运维

正则介绍以及grep

1223
来自专栏木子昭的博客

简单点! python匿名函数!

适用场景 懒得为函数起名 函数只用一次 好处 写起来方便 避免对函数命名空间的污染 用法 按照字典特定键排序 ? 对字典年龄进行排序 格式 lambda 参数 ...

28010
来自专栏linux驱动个人学习

contain_of宏定义

 Container_of在Linux内核中是一个常用的宏,用于从包含在某个结构中的指针获得结构本身的指针,通俗地讲就是通过结构体变量中某个成员的首地址进而获得...

3234
来自专栏向治洪

java造成内存泄露原因

一、Java内存回收机制  不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址。Java中对象是采用new或者反射的...

24410
来自专栏Java 源码分析

Java 虚拟机运行时数据区

运行时数据区: Java 虚拟机的运行时数据区按照大的可以分为线程独立使用的数据区,和所有线程共享的数据区。 一.线程独立使用数据区 1.程序计数器 程序计数器...

2695
来自专栏Android开发指南

7:多线程

2968
来自专栏转载gongluck的CSDN博客

Lua学习笔记

--Lua笔记-- --0.Lua开篇-- --http://www.cnblogs.com/stephen-liu74/archive/2012/06/11/...

5526

扫码关注云+社区

领取腾讯云代金券