Если в 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 будут содержать все документы.