Подтвердить что ты не робот

Кодировка UTF8 длиннее максимальной длины 32766

Я обновил свой кластер 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
}

Отображение индекса:

{
  "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" }
      }
    }
  }
}

Я искал документацию и не нашел ничего, связанного с максимальным размером поля. В разделе основных типов я не понимаю, почему я должен "исправить анализатор" для поля not_analyzed.

4b9b3361

Ответ 1

Таким образом, у вас возникает проблема с максимальным размером для одного термина. Когда вы установите поле not_analyzed, оно будет относиться к нему как к одному термину. Максимальный размер для одного термина в базовом индексе Lucene составляет 32766 байт, что, я считаю, жестко закодировано.

Два ваших основных параметра: либо изменить тип на двоичный, либо продолжить использование строки, но установить тип индекса "нет".

Ответ 2

Если вы действительно хотите 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,
        ],
    ],
],

В вашем случае вы, вероятно, захотите сделать, как сказал вам Джон Петреон, и установите "index": "no", но для тех, кто еще найдет этот вопрос после того, как я, как и я, выполнив поиск по этому Исключению, ваши варианты:

  • set "index": "no"
  • set "index": "analyze"
  • set "index": "not_analyzed" и "ignore_above": 256

Это зависит от того, как и как вы хотите фильтровать это свойство.

Ответ 3

Существует лучший вариант, чем тот, который опубликовал Джон. Потому что с этим решением вы больше не можете искать значение.

Вернуться к проблеме:

Проблема заключается в том, что значения полей по умолчанию будут использоваться как один термин (полная строка). Если этот термин/строка длиннее 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

Ответ 4

Мне нужно было изменить часть index отображения на no вместо not_analyzed. Таким образом, значение не индексируется. Он остается доступным в возвращаемом документе (из поиска, get,...), но я не могу его запросить.

Ответ 5

Я столкнулся с этой проблемой, изменив свой анализатор.

{
    "index" : {
        "analysis" : {
            "analyzer" : {
                "standard" : {
                    "tokenizer": "standard",
                    "filter": ["standard", "lowercase", "stop"]
                }
            }
        }
    }
}

Ответ 6

Если вы используете searchkick, обновите elasticsearch до >= 2.2.0 и убедитесь, что вы используете searchkick 1.3.4 или более поздней версии.

Эта версия searchkick устанавливает ignore_above = 256 по умолчанию, поэтому вы не получите эту ошибку, когда UTF > 32766.

Здесь обсуждается здесь.

Ответ 7

В Solr v6 + я изменил тип поля на text_general, и он решил мою проблему.

<field name="body" type="string" indexed="true" stored="true" multiValued="false"/>   
<field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/>

Ответ 8

Используя logstash для индексации этих длинных сообщений, я использую этот фильтр для усечения длинной строки:

    filter {
        ruby {
            code => "event.set('message_size',event.get('message').bytesize) if event.get('message')"
        }
        ruby {
            code => "
                if (event.get('message_size'))
                    event.set('message', event.get('message')[0..9999]) if event.get('message_size') > 32000
                    event.tag 'long message'  if event.get('message_size') > 32000
                end
            "
         }
     }

Он добавляет поле message_size, чтобы я мог сортировать самые длинные сообщения по размеру.

Он также добавляет тег длинного сообщения к тем, которые превышают 32000 КБ, поэтому я могу легко их выбирать.

Это не решает проблему, если вы намерены полностью индексировать эти длинные сообщения, но если, как и я, вы не хотите, чтобы они были в elasticsearch в первую очередь и хотите отследить их, чтобы исправить это, рабочего решения.