如何在ORM查询中为指定question_id下的每个answer_id取5条Comment记录?
获取指定问题下每个回答的前5条评论
数据表说明
以下是Comment表结构及示例数据:
| id | comment | answer_id | question_id |
|---|---|---|---|
| 1 | some comment | 2 | 1 |
| 2 | some comment | 2 | 1 |
| 3 | some comment | 42 | 1 |
| 4 | some comment | 42 | 1 |
| 5 | some comment | 42 | 1 |
| 6 | some comment | 42 | 1 |
| 7 | some comment | 2 | 1 |
| 8 | some comment | 2 | 1 |
| 9 | some comment | 2 | 1 |
| 10 | some comment | 2 | 1 |
| 11 | some comment | 2 | 1 |
| 12 | some comment | 42 | 1 |
| 13 | some comment | 2 | 1 |
| 14 | some comment | 2 | 1 |
| 15 | some comment | 2 | 1 |
| 16 | some comment | 2 | 1 |
| 17 | some comment | 42 | 1 |
| 18 | some comment | 42 | 1 |
| 19 | some comment | 42 | 1 |
| 20 | some comment | 42 | 1 |
| 21 | some comment | 42 | 1 |
Comment表用于存储回答和问题的评论,另外还有Answer表(存储回答数据)和Question表(存储问题数据)。
需求
针对特定question_id(比如1),获取每个关联answer_id(比如2和42)对应的前5条Comment记录。
现有问题
你当前的查询会返回该问题下的所有评论,无法实现“每个回答取前5条”的需求:
answer = Answer.objects.filter(question=question_id) answer_comment = Comment.objects.filter(answer_id__in=answer.values('id'))
解决方案
方法1:使用窗口函数(推荐,性能更优)
利用Django的Window和RowNumber函数,给每个回答下的评论标记行号,再筛选行号≤5的记录:
from django.db.models import Window, F from django.db.models.functions import RowNumber target_question_id = 1 # 获取该问题下的所有回答ID answer_ids = Answer.objects.filter(question=target_question_id).values_list('id', flat=True) # 给每个回答下的评论按ID升序标记行号(可根据需求调整排序字段) comments_with_row = Comment.objects.filter( answer_id__in=answer_ids, question_id=target_question_id ).annotate( row_num=Window( expression=RowNumber(), partition_by=F('answer_id'), order_by=F('id').asc() ) ) # 筛选每个回答的前5条评论 target_comments = comments_with_row.filter(row_num__lte=5)
方法2:循环查询每个回答的前5条
如果数据库不支持窗口函数,或者回答数量较少,可直接循环每个回答取前5条:
target_question_id = 1 answer_list = Answer.objects.filter(question=target_question_id) target_comments = [] for answer in answer_list: # 按ID升序取当前回答的前5条评论,排序规则可按需修改 comments = Comment.objects.filter(answer=answer).order_by('id')[:5] target_comments.extend(comments)
方法对比
- 窗口函数方法仅需一次数据库查询,性能更优,适合数据量大的场景;
- 循环查询方法代码更简单直观,但每个回答会触发一次查询,回答数量多时性能较差。
内容的提问来源于stack exchange,提问作者sodmzs2
相关产品推荐
相关产品推荐

