2010-12-02 26 views
0

J'ai ce scénario où je pensais que ce serait assez basique, mais j'ai découvert que je ne peux pas vraiment réaliser ce dont j'ai besoin. C'est pourquoi j'ai cette question pour un expert de think_sphinx. Le scénario est le suivant: J'ai besoin de faire une recherche dans une liste d'entreprises et de retourner seulement ceux qui ont une adresse (il peut y avoir plusieurs adresses par entreprise) qui appartient à une ville particulière ou pas du tout (ceci je peux faire).Recherche avec think_sphinx et filtrage des résultats

J'ai les modèles suivants:

class Company < ActiveRecord::Base 
    has_many :company_addresses 

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

et

class CompanyAddress < ActiveRecord::Base 
end 

Le companyAddress a une propriété CITY_ID. Sans boucler tous les enregistrements d'une recherche de sphinx, y a-t-il un moyen de réaliser la même chose plus facilement? J'utilise Rails 3.0.3 et thinking_sphinx.

Répondre

4

Vous voulez ajouter un attribut pointant vers les valeurs CITY_ID pour l'entreprise:

has company_addresses.city_id, :as => :city_ids 

Et puis vous pouvez filtrer sur les sociétés appartenant à une ville spécifique:

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

Si vous Vous n'avez pas de villes, c'est un peu plus compliqué, car la logique OU pour les filtres d'attributs est plus qu'un peu difficile au mieux. Idéalement, ce que vous voulez est un seul attribut qui contient 0 ou tous les ids de la ville. Cela dépend de votre base de données, car les fonctions MySQL et Postgres varient.

Comme une idée approximative, mais - cela pourrait fonctionner dans MySQL:

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

Postgres est raisonnablement similaire, bien que vous devrez peut-être utiliser une instruction CASE au lieu de IF, et vous voudrez certainement utiliser un couple de fonctions pour la concaténation des groupes:

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

(array_accum est fourni par la pensée Sphinx, car il n'y avait pas d'équivalent direct de GROUP_CONCAT dans PostgreSQL).

Quoi qu'il en soit, si vous avez besoin de cette approche, et obtenir le SQL tout compris, votre requête ressemble à quelque chose comme:

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

Cela correspondra à 0 (représentant pas de villes), ou la ville spécifique .

Enfin: si vous ne faites pas référence à l'association de company_addresses partout dans vos champs normaux et les attributs, vous devrez forcer à se joindre à votre define_index:

join company_addresses 

Espérons que fournit des indices assez - se sentir libre pour continuer la discussion ici ou sur the Google Group.

+0

Exactement ce dont j'avais besoin! Merci beaucoup! –