Кодировка 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" }
}
}
}
}
Я искал в документации и не нашел ничего связанного с максимальным размером поля. Согласно основные типы раздел я не понимаю, почему я должен "исправить анализатор" для
10 ответов:
таким образом, вы столкнулись с проблемой с максимальным размером для одного термина. Когда вы устанавливаете поле not_analyzed, оно будет рассматривать его как один единственный термин. Максимальный размер для одного термина в базовом индексе Lucene составляет 32766 байт, что я считаю жестко закодированным.
ваши два основных варианта - либо изменить тип на двоичный, либо продолжать использовать строку, но установить тип индекса на "нет".
если вы действительно хотите
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
это зависит от того, как вы хотите фильтровать по этому свойству.
есть лучший вариант, чем тот, который опубликовал Джон. Потому что с этим решением вы больше не можете искать по значению.
вернемся к проблеме:
проблема в том, что по умолчанию значения полей будут использоваться как один термин (полная строка). Если этот термин / строка длиннее 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
мне нужно изменить
index
часть отображения наno
вместоnot_analyzed
. Таким образом, значение не индексируется. Он остается доступным в возвращенном документе (из поиска, get,...), но я не могу запросить его.
один из способов обработки токенов, которые превышают предел lucene, заключается в использовании
truncate
фильтр. Похоже наignore_above
для ключевых слов. Чтобы продемонстрировать, я использую5
. Elasticsearch предлагает использовать ignore_above = 32766 / 4 =8191
так как символы UTF-8 могут занимать не более 4 байт. https://www.elastic.co/guide/en/elasticsearch/reference/6.3/ignore-above.htmlcurl -H'Content-Type:application/json' localhost:9200/_analyze -d'{ "filter" : [{"type": "truncate", "length": 5}], "tokenizer": { "type": "pattern" }, "text": "This movie \n= AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" }'
выход:
{ "tokens": [ { "token": "This", "start_offset": 0, "end_offset": 4, "type": "word", "position": 0 }, { "token": "movie", "start_offset": 5, "end_offset": 10, "type": "word", "position": 1 }, { "token": "AAAAA", "start_offset": 14, "end_offset": 52, "type": "word", "position": 2 } ] }
Я обошел эту проблему, изменив свой анализатор .
{ "index" : { "analysis" : { "analyzer" : { "standard" : { "tokenizer": "standard", "filter": ["standard", "lowercase", "stop"] } } } } }
если вы используете
searchkick
, обновить elasticsearch до>= 2.2.0
& убедитесь, что вы используете searchkick1.3.4
или позже.эта версия searchkick устанавливает
ignore_above = 256
по умолчанию, таким образом, вы не получите эту ошибку, когда UTF > 32766.это обсуждается здесь.
в 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"/>
используя 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 поле, так что я могу сортировать самые длинные сообщения по размеру.
Он также добавляет долго тег для тех, которые находятся над 32000kb, так что я могу выбрать их легко.
это не решает проблему, если вы намерены полностью индексировать эти длинные сообщения, но если, как и я, не хотите их иметь elasticsearch в первую очередь и хотят отслеживать их, чтобы исправить это, это рабочее решение.
я наткнулся на то же сообщение об ошибке с Drupal в Поиск вложений api модуль:
документ содержит по крайней мере один огромный термин в поле="saa_saa_file_entity" (чья кодировка UTF8 длиннее максимальной длины 32766), все из которых были пропущены. Пожалуйста исправьте анализатор для того чтобы не произвести такие термины.
изменение типа полей с
string
доFulltext
(in /администратором/настройка/поиск/поиск-АПИ/индекс/elastic_index/поля) решил проблему для меня.