0

こんにちは、投稿がいつ作成され、投票数によってランク付けされたかに基づいて投稿を返す関数を作成しました。これは餌用です。これがこれを行う効率的な方法であるかどうかはわかりませんが、何千もの投稿をふるいにかける可能性があるため、正しく行うことが重要です. ここではいくつか単純化し、各ステップを簡単に説明しました。私の現在の懸念事項と関数全体 (注釈なし) の投稿はその後です。

開始時間の引数は、何時間前に投稿を取得するかを指定します。たとえば、startHours=6 の場合、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 を作成します。これは、常に startHours 引数の 4 時間前です。

    endHours=startHours+4         #4 hour time window

ここで、unorderedPosts をスライスして、今から 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)))

ここで、タイム ウィンドウに適合する作成日を持つ投稿が少なくとも 1 つ見つかるまで、タイム ウィンドウを戻すループを作成します。無限ループを防ぐために check 変数を作成します (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
4

1 に答える 1