UTF8编码长度超过最大长度32766

jle*_*our 58 elasticsearch

我已经将我的Elasticsearch集群从1.1升级到1.2,并且在索引一个有点大字符串时出错.

{
  "error": "IllegalArgumentException[Document contains at least one immense term in field=\"response_body\" (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: '[7b 22 58 48 49 5f 48 6f 74 65 6c 41 76 61 69 6c 52 53 22 3a 7b 22 6d 73 67 56 65 72 73 69]...']",
  "status": 500
}
Run Code Online (Sandbox Code Playgroud)

索引的映射:

{
  "template": "partner_requests-*",
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  },
  "mappings": {
    "request": {
      "properties": {
        "asn_id": { "index": "not_analyzed", "type": "string" },
        "search_id": { "index": "not_analyzed", "type": "string" },
        "partner": { "index": "not_analyzed", "type": "string" },
        "start": { "type": "date" },
        "duration": { "type": "float" },
        "request_method": { "index": "not_analyzed", "type": "string" },
        "request_url": { "index": "not_analyzed", "type": "string" },
        "request_body": { "index": "not_analyzed", "type": "string" },
        "response_status": { "type": "integer" },
        "response_body": { "index": "not_analyzed", "type": "string" }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我搜索了文档,没有找到任何与最大字段大小相关的内容.根据核心类型部分,我不明白为什么我应该为一个not_analyzed字段"纠正分析仪" .

Joh*_*one 62

因此,您遇到的问题是单个术语的最大大小.当您将字段设置为not_analyzed时,它会将其视为一个单独的术语.底层Lucene索引中单个术语的最大大小为32766字节,我相信这是硬编码的.

您的两个主要选项是将类型更改为二进制或继续使用字符串,但将索引类型设置为"否".


Mik*_*ael 31

如果你真的想not_analyzed在房产上,因为你想做一些精确的过滤,那么你可以使用"ignore_above": 256

这是我在php中如何使用它的一个例子:

'mapping'    => [
    'type'   => 'multi_field',
    'path'   => 'full',
    'fields' => [
        '{name}' => [
            'type'     => 'string',
            'index'    => 'analyzed',
            'analyzer' => 'standard',
        ],
        'raw' => [
            'type'         => 'string',
            'index'        => 'not_analyzed',
            'ignore_above' => 256,
        ],
    ],
],
Run Code Online (Sandbox Code Playgroud)

在你的情况下,你可能想要像John Petrone告诉你那样设置,"index": "no"但是对于其他人发现这个问题之后,像我一样,搜索那个例外,那么你的选择是:

  • "index": "no"
  • "index": "analyze"
  • 设置"index": "not_analyzed""ignore_above": 256

这取决于您是否以及如何过滤该属性.

  • 如果您仍需要对该字段进行排序,这是最佳解决方案. (2认同)
  • 值得一提的是,如果数据已经存在于类型中,最好是使用`ignore_above`选项,这是一个非破坏性的变化而不是`index:no`,这是一个重大变化,你必须导出导入数据申请. (2认同)

Jas*_*zen 8

有一个比John发布的更好的选择.因为使用该解决方案,您无法再搜索该值.

回到问题:

问题是默认情况下,字段值将用作单个术语(完整字符串).如果该术语/字符串长于32766字节,则无法将其存储在Lucene中.

较旧版本的Lucene仅在术语太长时才会注册警告(并忽略该值).较新的版本会抛出异常.请参阅错误修正:https://issues.apache.org/jira/browse/LUCENE-5472

解:

最好的选择是使用长字符串值在字段上定义(自定义)分析器.分析器可以用较小的字符串/术语分割长字符串.这将解决太长期的问题.

如果您正在使用该功能,请不要忘记将分析器添加到"_all"字段.

可以使用REST API测试分析仪.http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-analyze.html

  • 非常有趣的答案,但在哪里可以找到将字符串字段拆分为标记的自定义分析器,但在搜索请求期间"合并"这些标记的整个值? (3认同)