Индексация данных с помощью C++. Проблемы с wchar_t


(Anton Kotelev) #1

Здравствуйте. Подскажите с таким вопросом. Программно отправляю данные на ES с использованием C++ по сокету. Когда посылаю пакеты, где строки представлены однобайтовыми символами - все хорошо. Но когда отправляются двухбайтные символы, то данные на ES не создаются. Точнее они создаются, но лишь до свойства, где идет двухбайтные символы.
Отправляю данные через BULK. Примерный формат отправляемого пакета (без HTTP-заголовков):

POST myindex/mytype
{"index" : { "_id" : "1"} }
{"first" : "value1" , "second" : "value2" , "third" : "value3"}

Двухбайтовую строку посылаю в поле "second". Данные из поля "first" появляются, а из остальных полей нет.


(Igor Motov) #2

А в какой кодировке вы эти данные отправляете?


(Anton Kotelev) #3

Кодировка UTF-8, но т.к. данные могут быть и других кодировок (по задаче), то пробовал перекодировать в UTF-16 и отправлял полученное на ES. Собственно первый байт в этом случае был равен 0x00, а далее уже значимый.


(Igor Motov) #4

А какие HTTP-заголовки в запросе? Хорошо бы на весь неработающий запрос в целом посмотреть.


(Anton Kotelev) #5

Сниферил через Wireshark.


(Igor Motov) #6

Нет, так точно не пойдет - вы мешаете вместе ASCII (UTF-8) с UTF-16. Вы пробовали все в UTF-8 посылать? Дамп с этим вариантом прислать можете?


(Anton Kotelev) #7

Когда отправляю все в UTF-8, то все работает, данные загружаются на ES. Но мне нужно сохранять одновременно и данные в UTF-16. Причем они будут идти смешанно - часть полей в ASCII, часть в UTF-16. Это возможно или требует каких-то дополнительных параметров на стороне ES?
P.S.: Данные в формате UTF-16 будут динамическими, т.е. для них mapping не настроишь при создании индекса.


(Igor Motov) #8

Это не возможно ни с параметрами на стороне ES ни без, так как в Elasticsearch просто нет никаких механизмов обнаружения внезапной смены кодировки в запросе. Я вообще не уверен, что это теоретически возможно. Например, широко известная фраза "Bush hid the facts" в ASCII может быть интерпретирована как "畂桳栠摩琠敨映捡獴" в UTF-16LE.

Так что вам будем необходимо привести запрос в нормальный вид перед отправкой его в Elasticsearch. Я одно не пойму, почему нельзя все перевести в UTF-8 перед отправкой?


(Anton Kotelev) #9

Даже если перевести в формат UTF-8 данные могут содержать нулевые символы (0х00). При их наличии еластик запрос на добавление данных не работает.


(Igor Motov) #10

А что вы делаете с этими данными? Как бы вы хотели elasticsearch эти нулевые символы обрабатывать? Как пробелы?


(Anton Kotelev) #11

Почему же пробелы?? В заголовке HTTP передается длина сообщения, а дальше уже задача парсинга значения по разделителям независимо от содержимого. Нужно только проверять границы текущей позиции считывания данных из пакета на основе дляны сообщения.
Просто иначе эта задача ложится на плечи программиста, используемого ES. А в случае добавления данных из высоконагруженных сторонних сервисов, данная проблема заставляет задуматься о каких-то костылях как при добавлении, так и извлечении данных для визуализации или обработки. ИМХО.


(Igor Motov) #12

Задача программиста, использующего elasticsearch, послать документ в elasticsearch в правильном формате. Если вы посылаете документ в формате JSON, то по спецификации, 0х00 в JSON должен быть закодирован:

  string = quotation-mark *char quotation-mark

  char = unescaped /
      escape (
          %x22 /          ; "    quotation mark  U+0022
          %x5C /          ; \    reverse solidus U+005C
          %x2F /          ; /    solidus         U+002F
          %x62 /          ; b    backspace       U+0008
          %x66 /          ; f    form feed       U+000C
          %x6E /          ; n    line feed       U+000A
          %x72 /          ; r    carriage return U+000D
          %x74 /          ; t    tab             U+0009
          %x75 4HEXDIG )  ; uXXXX                U+XXXX

  escape = %x5C              ; \

  quotation-mark = %x22      ; "

  unescaped = %x20-21 / %x23-5B / %x5D-10FFFF

Если быстрая пересылка двоичных данных является приоритетом, то вам следует посылать документы в формате SMILE вместо JSON.


(Anton Kotelev) #13

Хм. Понял. Спасибо за разъяснения.


(system) #14