Создайте фильтр в Sphinx со значением текста / строки - PullRequest
8 голосов
/ 21 апреля 2011

У меня установлен Sphinx Search в качестве поисковой системы, и я пытаюсь добавить в поиск несколько дополнительных функций, используя setFilter() и SetSelect(), которые позволят мне выполнять предложения WHERE/AND. Но всякий раз, когда я пытаюсь выполнить поиск, он не возвращает результатов вместо результатов.

Вот мой sphinx.conf: http://pastebin.com/M6Kd71u0

А вот код PHP:

require("sphinxapi.php");

$host = "localhost";
$port = 9312;
$index = "llgenre";
$select1 = "cartoon";
$label6 = "children";
$type = 4;
$limit = 20;
$ranker = SPH_RANK_PROXIMITY_BM25;
$mode = SPH_MATCH_ALL;

$sphinx = new SphinxClient();
$sphinx->setServer($host, $port);
$sphinx->setConnectTimeout(0);
$sphinx->setMatchMode($mode);
$sphinx->setRankingMode($ranker);
$sphinx->setSelect('*, select1="'.$select1.'" AND label6="'.$label6.'" AS mycond');
$sphinx->setFilter('mycond', array(1));

$res = $sphinx->query($type, $index);

die(var_dump($res));

Как искать по type = 4, фильтровать по select1 с cartoon и, наконец, по label6 с children?

1 Ответ

16 голосов
/ 08 мая 2011

Я считаю, что вы пытаетесь фильтровать строки как атрибуты.Ссылаясь на Sphinx FAQ , они описывают процедуру

Как фильтровать, сортировать или группировать по столбцу строки без атрибутов строки?

Вы можете сделатьвсе это, за исключением точной сортировки по длине по нескольким индексам.

Для фильтрации и группировки вы можете заменить строку уникальным числовым идентификатором.Иногда возможно создать словарь поиска в базе данных (например, для фиксированных списков городов или стран) или даже использовать существующий, заменить строки с их идентификаторами в этом словаре, затем отфильтровать и сгруппировать по этому идентификатору.Если нет, вы всегда можете заменить строку ее контрольной суммой, например.CRC32 () или (любые) 64 бита, взятые из MD5 () во время индексации (нет необходимости изменять таблицы!), Сохраните его с использованием sql_attr_uint или sql_attr_bigint соответственно, а затем отфильтруйте или сгруппируйте по этому атрибуту контрольной суммы. (Примечаниечто есть определенная вероятность коллизий CRC32 (), если у вас есть миллионы строк, но практически нет шансов коллизий MD5 ().)

Итак, в моем sphinx.conf у меня может быть следующее...

sql_query = SELECT CRC32(string_field) AS `string_field` FROM `table`

sql_attr_uint = string_field

Тогда в PHP я бы применил фильтр к полю следующим образом ...

$sphinx->SetFilter('string_field', array(crc32( 'filter_string' ));

-

К сожалению, PHP имеетдосадная проблема (ошибка?) при преобразовании в crc32 ... что-то, содержащее целые числа без знака или что-то еще ..

Я использую следующую функцию для правильного преобразования

class Encode {
    public static function crc32($val){
        $checksum = crc32($val);
        if($checksum < 0) $checksum += 4294967296;
        return $checksum;
    }
}

-

Будьте осторожны с регистром символов!Вы можете выбрать преобразование столбца в нижний регистр при индексации, например.

sql_query = SELECT CRC32(LOWER(string_field)) AS `string_field` FROM `table`

и поиске ...

$sphinx->SetFilter('string_field', array(crc32(strtolower( 'Filter_String' )));
...