Поиск отношения has_many с Rails и Thinking Sphinx - PullRequest
1 голос
/ 11 октября 2011

Я пытаюсь создать функцию поиска для моего приложения Rails 3 с использованием Sphinx 0.9.10 и Thinking Sphinx. Я хочу, чтобы пользователи искали песни. Мои песни могут иметь много треков. Например, песня «Beautiful song» может содержать звуковую дорожку со ссылкой на mp3 и видеодорожку со ссылкой на YouTube.

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

Мои пользователи должны иметь возможность вводить ключевое слово и фильтровать, чтобы найти песни, которые содержат хотя бы одну звуковую дорожку, хотя бы одну видеодорожку или хотя бы одну из каждой.

Пока у меня есть следующая модель для моих песен:

class Song < ActiveRecord::Base
  ...
  has_many :tracks
  ...

  define_index('song') do
    indexes                               :name, 
                                          :sortable   => :true
    has     "tracks.media LIKE '%audio%'",:as         => :audio,
                                          :type       => :boolean
    has     "tracks.media LIKE '%video%'",:as         => :video,
                                          :type       => :boolean
  end
end

В моей модели Track я использую сериализованное медиа-поле. Ruby видит его как хеш, содержащий среди прочего ссылку и тип (например, 'audio / m4u' или 'video / mp4'). MySQL видит это как строку.

class Track < ActiveRecord::Base
  belongs_to :Song

  serialize :media
end

В моем контроллере Song есть что-то вроде этого:

class CoursesController < ApplicationController
  def search
      with_params[:audio] = true if search[:audio] == true || search[:audio] == 'true'  || search[:audio] == "1"
      with_params[:video] = true if search[:video] == true || search[:video] == 'true' || search[:video] == "1"

      @songs = Song.search(
      keywords,
      :with       => with_params
      ...
      )
      ...
  end
end

Результаты поиска хороши, когда у меня есть только один трек, связанный с песней.

Но когда у меня есть несколько треков, кажется, что поисковый индекс видит только первый трек: если «Красивая песня» имеет первый трек «видео» и второй «аудио», он будет отображаться только в результатах поиска, если Я выбираю «видео» в своих фильтрах, нет, если я выбираю «аудио».

Чего мне не хватает?

1 Ответ

2 голосов
/ 11 октября 2011

Что вам нужно сделать, это сравнить с объединенными значениями столбца медиа.В MySQL это будет выглядеть примерно так:

GROUP_CONCAT(`tracks`.`media` SEPARATOR ' ')

Или для PostgreSQL (с версией 8.4 или выше - дайте мне знать, если вы используете более старую версию):

array_to_string(array_agg("tracks"."media"), ' ')
...