Мобильная
версия

Sphinx - комбинация множественных OR и AND

Дата: Категория: Sphinx

Данная заметка рассчитана на пользователей знакомых со sphinx на приемлемом уровне.
Это всего лишь небольшой рецепт.

Про sphinx можно подробно изучить в документации.


Со sphinx я работаю достаточно давно, настолько давно что простые и не очень операции не вызывают у меня смущения.

Сегодня же мне предстояло сделать следующее - 
Предположим у нас есть таблица в которой указаны места временного проживания (гостиницы и мотели)
В них могут быть и могут не быть трансфер и полное питание

id type transfer full_nutrion
1 1 1 0
2 1 0 1
3 2 1 0
4 2 0 1

где

  • id (int) - Идентификатор места
  • type (int) - Идентификатор типа (1 - гостиница, 2 - мотель)
  • transfer (bool) - наличие трансфера
  • full_nutrion (bool) - наличие питания

Предположим что нам нужно выбрать гостиницы в которых есть трансфер, и мотели в которых есть питание.
SQL запрос выглядел бы примерно так

SELECT id FROM table
WHERE (type = 1 AND transfer = 1) 
OR (type = 2 AND full_nutrion = 1)

Все просто - так мы получаем все ИД нужных нам объектов.

При работе со sphinx можно работать через sql синтаксис (пример выше), или через задание фильтров (setFilter)
Если мы работаем через sql то проблем не составит добавить через addQuery немного измененный запрос

SELECT id, (type = 1 AND transfer = 1) 
OR (type = 2 AND full_nutrion = 1) AS cond
FROM table
WHERE cond <> 0

Так как sphinx не поддерживает условия OR (ИЛИ) то приходится прибегать к таким методам.

Мы обозначили все наше условие как переменную и уже ведем выборку по ней.

Отлично, но только в том случае если выборка ведется с помощью sql.
А если у нас на руках уже есть много прекрасно работающего кода написанного с помощью setFilter? Как тогда?

В таком случае нам на помощь приходит отличная команда setSelect.

Она, как и в случае с sql запросом, создает дополнительную переменную по нашему условию, чтобы в будущем мы смогли у ней применить setFilter

Не совсем ясно? Ну вот тогда пример кода для выборки из нашей таблицы.

$client->setSelect('*,(type = 1 AND transfer = 1) OR (type = 2 AND full_nutrion = 1) AS filter');
$client->setFilter('filter', array(1));

Здесь происходит следующее - с помощью команды setSelect мы добавляем к стандартному запросу (звездочка вначале) наше условие, обернув его в переменную filter.
А с помощью setFilter уже фильтруем все данные по этому полю.

Как выяснилось - все достаточно просто.

PS
"Only possible in 0.9.9, using the SetSelect." - все это доступно для sphinx 0.9.9 и выше

Теги: #setSelect, #setFilter, #sphinx

Ваша оценка:

Рейтинг: 9.7 (Оценок: 3)

Комментарий:

Copyright © DOC_tr 2015-2017 г. Все права защищены
Яндекс.Метрика
Перейти к мобильной версии