Привет, я создал функцию, которая будет возвращать сообщения, основанные на том, когда они были созданы и ранжированы по количеству голосов, которые у них есть. Это для фида. Я не уверен, что если это эффективный способ сделать это, и очень важно, чтобы я понял это правильно, потому что это потенциально могло бы просеиваться через тысячи сообщений. Я упростил его здесь и кратко объяснил каждый шаг. Мои текущие проблемы и пост целой функции (без аннотаций) после.Как оптимизировать эту функцию для возврата сообщений в фид. Django
Аргумент начальных часов - это то, сколько часов назад для получения сообщений. Например, если startHours = 6, будут возвращены только сообщения, созданные после шести часов назад.
def rank(request, startHours):
Сначала я заказываю все должности по голосам
unorderedPosts=Post.objects.order_by('-votes')
Тогда сообщения исключаются по категориям пользователь указал
if request.user.is_authenticated():
preferences=request.user.categorypreference_set.filter(on=False)
for preference in preferences:
unorderedPosts=unorderedPosts.exclude(category_name=preference.category_name)
Тогда я делаю endHours, который всегда 4 часа до начала часаНапример аргумент
endHours=startHours+4 #4 hour time window
Теперь я нарезаю неупорядоченные поства и получаю только те, которые были созданы во временном окне startHours для endHours. Например, если startHours = 4, то будут возвращены только сообщения, созданные после 4 часов назад, но до 8 часов назад.
posts=unorderedPosts.filter(created__gte=(timezone.now()-datetime.timedelta(hours=endHours)))
posts=posts.exclude(created__gte=(timezone.now()-datetime.timedelta(hours=startHours)))
Теперь я сделать петлю, которая будет двигать окно времени назад, пока по крайней мере один пост не найден, который имеет дату создания, которая соответствует окно времени. Я делаю переменную проверки для предотвращения бесконечного цикла (цикл прекратится, если в течение 200 часов не будет найдено сообщений).
count=posts.count()
check=endHours
while count<1 and endHours<(check+200):
endHours+=4
startHours+=4
posts=unorderedPosts.filter(created__gte=(timezone.now()-datetime.timedelta(hours=endHours)))
posts=posts.exclude(created__gte=(timezone.now()-datetime.timedelta(hours=startHours)))
count=posts.count()
if count>=1: return posts, endHours
return posts
Моя самая большая забота заключается в том, чтобы задать запрос ВСЕ сообщений в начале. Эта функция предназначена для возврата сообщений в малые временные окна, будет ли она излишне замедлиться путем ранжирования всех сообщений в базе данных? Я знаю, что запросы django/python довольно эффективны, но не будут ранжировать набор, содержащий тысячи объектов, громоздким для этой функции?
Если это проблема, как я могу сделать ее более эффективной, сохраняя все доступным?
Это сообщение целиком.
def rank(request, startHours):
unorderedPosts=Post.objects.order_by('-upVote')
if request.user.is_authenticated():
preferences=request.user.categorypreference_set.filter(on=False)
for preference in preferences: #filter by category preference
unorderedPosts=unorderedPosts.exclude(category_name=preference.category_name)
endHours=startHours+4 #4 hour time window
posts=unorderedPosts.filter(created__gte=(timezone.now()-datetime.timedelta(hours=endHours)))
posts=posts.exclude(created__gte=(timezone.now()-datetime.timedelta(hours=startHours)))
count=posts.count()
check=endHours
while count<1 and endHours<(check+200):
endHours+=4
startHours+=4
posts=unorderedPosts.filter(created__gte=(timezone.now()-datetime.timedelta(hours=endHours)))
posts=posts.exclude(created__gte=(timezone.now()-datetime.timedelta(hours=startHours)))
count=posts.count()
if count>=1: return posts
return posts
Вы сделали несколько хороших предложений! Теперь я делаю временные окна исходящими из следующего последнего сообщения, а не итерациями через каждое последующее окно. И я переключил порядок сортировки, чтобы делать категории сначала, чем время, и, наконец, голоса. Я искал попытку подзапроса, но обнаружил, что мой конец (mysql) не подходит к этому методу. Большое спасибо за понимание! –
Временные окна сильно зависят от того, что вы пытаетесь сделать - если вы ищете, скажем, определенное минимальное количество сообщений, независимо от времени, есть другие способы сделать это. И, да, подзапросы - это хит или промах. –