J'ai un modèle utilisateur et un modèle cd connecté via une table de jointure 'cds_users'. J'essaye de retourner un hachage d'utilisateurs plus chaque CD qu'ils ont en commun avec l'utilisateur original.Le moyen le plus rapide de rechercher deux modèles connectés via une table de joint dans des rails ayant un grand jeu de données
@user.users_with_similar_cds(1,4,5)
# => {:bob => [4], :tim => [1,5]}
Y a-t-il un moyen meilleur/plus rapide de le faire sans trop boucler? Peut-être un moyen plus direct?
def users_with_similar_cds(*args)
similar_users = {}
Cd.find(:all, :conditions => ["cds.id IN (?)", args]).each do |cd|
cd.users.find(:all, :conditions => ["users.id != ?", self.id]).each do |user|
if similar_users[user.name]
similar_users[user.name] << cd.id
else
similar_users[user.name] = [cd.id]
end
end
end
similar_users
end
[plus]
Prendre la jointure idée modèle, je pourrais faire quelque chose comme ça. Je vais appeler le modèle «joint».
def users_with_similar_cds(*args)
similar_users = {}
Joined.find(:all, :conditions => ["user_id != ? AND cd_id IN (?)", self.id, args]).each do |joined|
if similar_users[joined.user_id]
similar_users[joined.user_id] << cd_id
else
similar_users[joined.user_id] = [cd_id]
end
end
similar_users
end
Serait-ce le moyen le plus rapide pour les grands ensembles de données?
Dans mes tests, cela n'a pas été plus rapide. Peut-être que sur des ensembles de données plus grands ce serait. – MediaJunkie
Hrm. Il semble probable que ce serait - dans le code original, vous faites une requête pour obtenir les CD, puis une autre requête pour chaque utilisateur trouvé. La variante find_by_sql fait tout le shebang dans une requête, bien qu'il s'agisse d'une jointure avec un group_concat. Si votre jeu de données est petit, le fait que les requêtes sur une seule table soient plus rapides que les jointures pourrait même faire l'affaire, mais une fois que vous aurez obtenu beaucoup d'utilisateurs similaires, le surcoût de toutes ces requêtes vous embêtera. Vous pouvez également vérifier que vous avez des index sur toutes les colonnes foo_id. –