Выборка документов с отрицательным условием “NOT MATCH” в Sphinx’e
Если в Sphinx’e выполнить запрос, содержащий только отрицательное условие в MATCH секции, увидим такую ошибку:
SELECT * FROM products WHERE match('!leggings');
***ERROR 1064 (42000): index products: query is non-computable (single NOT operator)***
## Такой запрос нельзя выполнить
Sphinx не сможет выполнить такую выборку, т.к. он нигде не хранит весь список документов. В индексах находятся только прямые соответствия между ключевыми словами и документами. Поэтому поисковик не может выбрать все документы и отфильтровать те, в которых не встречается указанного ключевого слова или фразы.
Это можно решить создав виртуальную колонку-индекс с уникальной строкой, которая будет повторяться в каждом документе. Пусть такой строкой будет “_all“, тогда запрос для построения индекса в Sphinx’e мы изменим таким образом:
source index_source
{
type = mysql
...
sql_query = SELECT id, title, body, **'_all' as default_text**
FROM products
...
}
## Добавляем виртуальную колонку в индекс
Тогда, после индексации, нужный нам результат мы получим следующим запросом:
SELECT * FROM products WHERE match**('_all !leggings')**;
Стоит обратить внимание, что этот прием имеет ряд нюансов. Во-первых увеличится размер индекса на диске. Это будет незаметно на крупных документах с большим количеством текста. Но если речь идет о большом количестве простых документов (например, индекс по названию товаров), это может увеличить индекс на несколько десятков процентов. Во-вторых, предлагаемый запрос может работать медленно на больших индексах, т.к. искомую строку _all будут содержать все документы.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: