Извлечение случайных записей из базы данных в зависимости от значения атрибута до предела и завершение другими, если предел не достигнут - PullRequest
0 голосов
/ 03 ноября 2018

Я использую Django с Postgres.

На странице я могу показать список рекомендуемых предметов, скажем, 10.

  1. Если в базе данных у меня больше элементов, чем 10, я хочу получить их случайным образом / (лучше повернуть).

  2. Если количество избранных предметов меньше 10, получите все рекомендуемые предметы и добавьте в список до 10 не признаваемых предметов.

Поскольку случайный выбор занимает больше времени в базе данных, я делаю выборку в python:

count = Item.objects.filter(is_featured=True).count()

        if count >= 10:
            item = random.sample(list(Item.objects.filter(is_featured=True))[:10])
        else:
            item = list(Item.objects.all()[:10])

В приведенном выше коде пропущен случай, когда выбрано менее 10 (например, 8 для добавления 2 неучтенных).

Я могу попытаться добавить новый запрос, но я не знаю, является ли это эффективным поиском, используя для этого 4-5 запросов.

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Метод SQL: Вы можете достичь этого с помощью оператора SQL, подобного следующему:

SELECT      uuid_generate_v4(), *
FROM        table_name
ORDER BY    NOT is_featured, uuid_generate_v4()
LIMIT 10;

Объясните : сгенерированный UUID должен симулировать случайность (для целей электронной коммерции этого должно быть достаточно). При сортировке строк по NOT is_featured поместит строки is_featured сверху; и автоматически выводить строки до 10 пределов, если в них нет рекомендуемых элементов.

0 голосов
/ 03 ноября 2018

Лучшее решение, которое я смог найти, это:

 from itertools import chain
 items = list(chain(Item.objects.filter(is_featured=True).order_by('?'), Item.objects.filter(is_featured=False).order_by('?')))[:10]

Таким образом, порядок наборов запросов сохраняется, но недостатком является то, что items становится списком, а не набором запросов. Вы можете видеть больше деталей в этом SO Ответе . К вашему сведению: есть несколько фантастических решений, таких как Q или pipe, но они не сохраняют порядок запросов.

...