Фильтр по полиморфным ассоциациям thinking sphinx

#ruby-on-rails #ruby #filtering #sphinx #thinking-sphinx

#ruby-on-rails #ruby #фильтрация #сфинкс #мышление-сфинкс

Вопрос:

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

 class Post < ActiveRecord::Base
  has_many :timeline_items, :as=>:subject

  define_index do
    ....?
  end
end

class TimelineItem < ActiveRecord::Base
  belongs_to :subject, :polymorphic=>true
  belongs_to :actor, :polymorphic=>:true
end
  

Я хочу получить все сообщения, принадлежащие конкретным участникам с помощью thinking-sphinx.

В ActiveRecord я бы сделал, как

Post.where('timeline_items.actor_type = "User" AND timeline_items.actor_id IN [1,2,3]).includes(:timeline_items)

Мой вопрос в том, какие индексы должны определять и какой запрос использовать, чтобы получить те же результаты с помощью thinking-sphinx?

Обновление Однако мне также нужно фильтровать сообщения по разным типам актеров, таким как: Post.where('timeline_items.actor_type = "Group" AND timeline_items.actor_id IN [1,2,3]).includes(:timeline_items)

Ответ №1:

Попробуйте следующее:

 define_index do
  # ...
  has timeline_items.actor.id, :as => :actor_ids
end
  

И затем для поиска:

 Post.search 'foo', :with => {:actor_ids => [1,2,3]}
  

Как подробно описано в комментариях, если вам нужно отфильтровать значения определенного класса в этих полиморфных ассоциациях, тогда вам нужно будет создать другую ассоциацию только для этого класса. Это потому, что Sphinx не имеет понятия о хэшах / парах ключ-значение, и поэтому не может отслеживать, какие идентификаторы принадлежат каким классам.

Как только у вас появится эта новая ассоциация, добавьте для нее атрибут, похожий на приведенный выше — возможно, такой:

 has user_timeline_items.actor.id, :as => :user_actor_ids
  

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

1. Спасибо за ваш ответ, но проблема в том, что у меня могут быть повторяющиеся идентификаторы, потому что это полиморфная ассоциация. Например, если я могу иметь actor_type="User" and actor_id=1 а также actor_type="Group" and actor_id=1 поэтому мне нужно отфильтровать по actor_type области, ограниченной до actor_id

2. О, я понимаю. С этим нелегко справиться — в Sphinx нет понятия пар ключ-значение.

3. Если бы вы могли создать отдельную ассоциацию с дополнительными условиями (возможно, user_actors), а затем добавить атрибуты через нее вместо этого, тогда это могло бы сработать?

4. Да, это было решение, которое я придумал. Пожалуйста, обновите свой ответ, чтобы я мог его принять.