Sphinx со строковыми атрибутами UTF-8

У меня есть индекс Sphinx с документами UTF-8, в частности с именами художников. По разным причинам у нас есть имя и как поле (indexed_name), и как атрибут (name). Когда я ищу документ, я нахожу его правильно, но атрибут возвращается поврежденным:

mysql> select name from artist where match('@indexed_name Sánchez') limit 3;
+---------+--------+-----------------------+
| id      | weight | name                  |
+---------+--------+-----------------------+
| 7843884 |   2642 | Sarita Sánchez     |
| 8519538 |   2642 | Cristhian  Sánchez |
| 3853986 |   2627 | Alfonso  Sánchez   |
+---------+--------+-----------------------+
3 rows in set (0.02 sec)

Похоже, атрибуты изначально были UTF-8, но были обработаны как ISO-8859-1, а затем преобразованы обратно в UTF-8. Когда я делаю это в Ruby, похоже, что это происходит во второй раз:

[1] pry(main)> rs = Thebes::Sphinxql::Query.run("select name from artist where match('@indexed_name Sánchez')")
=> #<Mysql2::Result:0x000000029bebf8 (omitted...)
[2] pry(main)> name = rs.first['name']
=> "Sarita SÃ\u0083¡nchez"

Это ошибка в Sphinx или я что-то не так делаю?

Я могу изменить его, прокручивая его через ISO-8859-1 и UTF-8:

[4] pry(main)> name.encode!("ISO-8859-1")
=> "Sarita S\xC3\x83\xC2\xA1nchez"
[5] pry(main)> name.force_encoding("UTF-8")
=> "Sarita Sánchez"
[6] pry(main)> name.encode!("ISO-8859-1")
=> "Sarita S\xC3\xA1nchez"
[7] pry(main)> name.force_encoding("UTF-8")
=> "Sarita Sánchez"

Однако будет ли это работать для символов из других наборов символов ISO-8859-* и для вещей, которым на законных основаниях требуется Unicode?

Обновление 1:

Ответ на второй вопрос – нет. Поиск турецких имен:

mysql> select name from artist where match('@indexed_name ÖZDEMİR') limit 3;

+---------+--------+-------------------------------+
| id      | weight | name                          |
+---------+--------+-------------------------------+
| 1753230 |   2664 | Nurullah Alper ÖZDEMİR |
| 6973956 |   2664 | YİĞİT ÖZDEMİR |
| 9133770 |   2664 | TAHA ÖZDEMİR           |
+---------+--------+-------------------------------+
3 rows in set (0.01 sec)

Вторым там должен быть "YİĞİT ÖZDEMİR".

[2] pry(main)> rs = Thebes::Sphinxql::Query.run("select name from artist where match('@indexed_name ÖZDEMİR') limit 3")
=> #<Mysql2::Result:0x000000047779b0...
[5] pry(main)> name = rs.to_a[1]['name'].dup
=> "YÃ\u0084°Ã\u0084žÃ\u0084°T Ã\u0083â\u0080\u0093ZDEMÃ\u0084°R"
[6] pry(main)> name.encode!("ISO-8859-1")
=> "Y\xC3\x84\xC2\xB0\xC3\x84\xC5\xBE\xC3\x84\xC2\xB0T \xC3\x83\xE2\x80\x93ZDEM\xC3\x84\xC2\xB0R"
[7] pry(main)> name.force_encoding("UTF-8")
=> "YİĞİT ÖZDEMİR"
[8] pry(main)> name.encode!("ISO-8859-1")
Encoding::UndefinedConversionError: U+017E from UTF-8 to ISO-8859-1
from (pry):8:in `encode!'

Я не уверен, как Ö превратился в Ö, который, по-видимому, имеет ширину пять байтов...

Обновление 2:

Я не хочу публиковать весь свой sphinx.conf, но вот конфигурация используемого здесь индекса. Он сгенерирован Thinking Sphinx.

source artist_core_0
{
  type = mysql
  sql_host = (omitted)
  sql_user = (omitted)
  sql_pass = (omitted)
  sql_db = (omitted)
  sql_query_pre = SET NAMES utf8
  sql_query_pre = SET TIME_ZONE = '+0:00'
  sql_query = (omitted)
  sql_query_range = SELECT IFNULL(MIN(`id`), 1), IFNULL(MAX(`id`), 1) FROM `artists` 
  sql_attr_uint = sphinx_internal_id
  sql_attr_uint = sphinx_deleted
  sql_attr_uint = class_crc
  sql_attr_float = latitude
  sql_attr_float = longitude
  sql_attr_string = sphinx_internal_class
  sql_attr_string = name
  sql_attr_string = homepage
  sql_attr_string = image
  sql_attr_string = city
  sql_attr_string = state
  sql_attr_string = postal_code
  sql_attr_string = country
  sql_query_info = SELECT * FROM `artists` WHERE `id` = (($id - 0) / 6)
}

index artist_core
{
  source = artist_core_0
  path = (omitted)
  morphology = libstemmer_en, libstemmer_fr, libstemmer_tr, libstemmer_es, libstemmer_de, libstemmer_it
  charset_type = utf-8
  min_prefix_len = 3
  enable_star = 1
}

index artist
{
  type = distributed
  local = artist_core
}

person Watts    schedule 09.02.2012    source источник
comment
Не могли бы вы прикрепить sphinx.conf ?   -  person Sergei Lomakov    schedule 10.02.2012


Ответы (1)


Не бери в голову. Данные в нашей базе данных были закодированы дважды.

person Watts    schedule 14.03.2012