J'ai trois entrées provenant d'un formulaire. Ils sont name
, neighborhoods
et tags
. Les quartiers et les tags sont des listes de chaînes de boîtes multi-sélection. Voici ma requête en cours:Recherche pondérée dans Django
q = Restaurant.objects.filter(name__icontains=name)
q = q.filter(neighborhoods__name__in=neighborhoods)
for tag in tags:
q = q.filter(tags__name=tag)
q = q.order_by('name').distinct()
qui va chercher actuellement tous les restaurants qui ont toutes les balises et tous les quartiers. J'ai un peu de mal à faire une recherche pondérée. Fondamentalement, pour chaque étiquette et le voisinage qui correspond, je veux ajouter un point à une colonne de poids. Ensuite, je vais commander au poids et même si un restaurant correspond seulement à deux des trois étiquettes, il sera toujours montré (son poids serait de 2). Ceci afin d'empêcher 0 résultats et de montrer le plus proche possible. De plus, je veux exiger qu'au moins 1 point soit requis pour choisir un restaurant.
je suppose que dans SQL ce serait quelque chose comme:
SELECT *,
(SELECT COUNT(1)
FROM tags t
WHERE t.name IN (%s)
) AS weight
FROM restaurants
WHERE weight > 0
ORDER BY weight DESC
Attendez une minute ici ... c'est juste le nombre de tags pour le restaurant, pas le nombre de tags qui correspondent à la liste de tags. J'ai besoin de quelque chose comme '.annotate (num_tags = Count ('tags__name__in' = tags))' –
Non, le code 'q = q.filter (tags__name__in = tags)' limite les lignes à inclure uniquement les balises correspondantes. '.annotate (Count ('tags__name'))' regroupe les enregistrements par tout autre chose que l'enregistrement de variable. Si vous recherchez 5 balises, ayez 3 restaurants, A, B et C; et A correspond à 1 tag, B 3 et C 4, puis après les lignes d'annotation sont (A: num_tags 1, B: num_tags 3, C: num_tags 4) et 'filter()' supprime A, laissant B et C. Je peux vous dire que '.annotate (num_tags = Count ('tags__name__in' = tags))' lancerait une erreur. L'argument pour Count est juste le nom du champ, pas une clause comme dans le filtre. –
ok, mon mauvais. Merci beaucoup! –