From c28fbbeb09d186423d65150ca163279ac148c02e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 4 Jan 2022 16:33:19 -0800 Subject: [PATCH] Uses single query to get suggested users --- bookwyrm/suggested_users.py | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/bookwyrm/suggested_users.py b/bookwyrm/suggested_users.py index 86c181a2..5769ca8b 100644 --- a/bookwyrm/suggested_users.py +++ b/bookwyrm/suggested_users.py @@ -2,7 +2,7 @@ import math import logging from django.dispatch import receiver -from django.db.models import signals, Count, Q +from django.db.models import signals, Count, Q, Case, When, IntegerField from bookwyrm import models from bookwyrm.redis_store import RedisStore, r @@ -84,24 +84,17 @@ class SuggestedUsers(RedisStore): def get_suggestions(self, user, local=False): """get suggestions""" values = self.get_store(self.store_id(user), withscores=True) - results = [] + annotations = [ + When(pk=int(pk), then=self.get_counts_from_rank(score)["mutuals"]) + for (pk, score) in values + ] # annotate users with mutuals and shared book counts - for user_id, rank in values: - counts = self.get_counts_from_rank(rank) - try: - user = models.User.objects.get( - id=user_id, is_active=True, bookwyrm_user=True - ) - except models.User.DoesNotExist as err: - # if this happens, the suggestions are janked way up - logger.exception(err) - continue - user.mutuals = counts["mutuals"] - if (local and user.local) or not local: - results.append(user) - if len(results) >= 5: - break - return results + users = models.User.objects.filter( + is_active=True, bookwyrm_user=True, id__in=[pk for (pk, _) in values] + ).annotate(mutuals=Case(*annotations, output_field=IntegerField(), default=0)) + if local: + users = users.filter(local=True) + return users[:5] def get_annotated_users(viewer, *args, **kwargs):