Поиск с использованием мышления_сфинкса и фильтрация результатов - PullRequest
0 голосов
/ 02 декабря 2010

У меня есть этот сценарий, в котором я думал, что он будет довольно простым, но обнаружил, что я не могу действительно достичь того, что мне нужно.Вот почему у меня есть вопрос к эксперту thinking_sphinx.

Сценарий таков: мне нужно выполнить поиск в списке компаний и вернуть только тех, у кого есть адрес (компания может иметь много адресов)который принадлежит конкретному городу или вообще отсутствует (это я могу сделать).

У меня есть следующие модели:

class Company < ActiveRecord::Base
    has_many :company_addresses

    define_index
      indexes :name
      indexes :description
      indexes :keywords
    end
end

и

class CompanyAddress < ActiveRecord::Base
end

Адрес компанииимеет свойство city_id.Не просматривая все возвращенные записи из поиска сфинксов, есть ли способ легче достичь того же самого?

Я использую Rails 3.0.3 и think_sphinx.

1 Ответ

4 голосов
/ 03 декабря 2010

Вы захотите добавить атрибут, указывающий на значения city_id для компании:

has company_addresses.city_id, :as => :city_ids

И затем вы можете отфильтровать по компаниям, принадлежащим определенному городу:

Company.search 'foo', :with => {:city_ids => @city.id}

Если вы хотите, чтобы оба соответствовали определенному городу или не имеют городов, это немного сложнее, поскольку логика ИЛИ для фильтров атрибутов в лучшем случае более сложна.В идеале вам нужен отдельный атрибут, который содержит либо 0, либо все идентификаторы города.Это зависит от вашей базы данных, поскольку функции MySQL и Postgres различаются.

Хотя это грубая идея - в MySQL это может работать:

has "IF(COUNT(city_id) = 0, '0', GROUP_CONCAT(city_id SEPARATOR ',')",
  :as => :city_ids, :type => :multi

Postgres достаточно похож, хотя вы можетенеобходимо использовать оператор CASE вместо IF, и вам определенно потребуется использовать несколько функций для объединения групп:

array_to_string(array_accum(city_id, '0')), ',')

(array_accum предоставляется Thinking Sphinx, так какне было прямого эквивалента GROUP_CONCAT в PostgreSQL).

В любом случае, если вам нужен этот подход и все SQL вычислены, тогда ваш запрос выглядит примерно так:

Company.search 'foo', :with => {:city_ids => [0, @city.id]}

Это будетсовпадать либо с 0 (не представляющим города), либо с конкретным городом.

Наконец: если вы не ссылаетесь на связь company_addresses нигде в своих обычных полях и атрибутах, вам нужно будет принудительно присоединиться к вашемуdefine_index:

join company_addresses

Надеюсь, это даст достаточно подсказок - не стесняйтесь продолжить обсуждение здесь или в Группе Google .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...