Active Record条件查询:如何获取3位评论达标且高评分的医生
高效实现3位优质医生查询的ActiveRecord方案
兄弟,你原来的写法太依赖Ruby层处理数据了,不仅代码绕,数据量大的时候性能会拉胯!直接用ActiveRecord结合数据库聚合查询来搞,所有统计、筛选、排序都交给数据库做,高效又简洁,直接上代码:
def get_three_best_doctors Doctor .left_joins(:reviews) .group(:id) .having("COUNT(reviews.id) > 1") .having("AVG(reviews.rating) >= 4") .order("AVG(reviews.rating) DESC") .limit(3) end
给你拆解下每个步骤的作用:
- left_joins(:reviews):关联医生和评论表,确保能拿到每个医生对应的所有评论数据(用
left_joins比joins更稳妥,避免漏掉有评论但关联时被过滤的情况,不过其实这里用joins也能行,因为后面的条件会筛掉没评论的医生)。 - group(:id):按医生ID分组,这样才能对每个医生的评论做聚合统计(比如计数、求平均值)。
- having("COUNT(reviews.id) > 1"):筛选出评论数超过1条的医生,这里用
COUNT(reviews.id)是因为它会忽略评论表中NULL的行,统计真实有效的评论数量,比COUNT(*)更准确。 - having("AVG(reviews.rating) >= 4"):直接用数据库的AVG函数计算每个医生的平均评分,筛选出评分≥4的医生,这比把所有评论数据拉到Ruby层再计算快太多。
- order("AVG(reviews.rating) DESC"):按平均评分从高到低排序,这样取前3个就是评分最高的优质医生。
- limit(3):让数据库直接返回前3条结果,减少内存占用,不用在Ruby层再做截取。
对比你原来的写法,这个方案把所有耗时的操作都放在数据库层面完成,避免了加载大量不必要的数据到内存,性能提升非常明显。如果你的评论表中评分字段不是rating,记得替换成你实际的字段名就行。
内容的提问来源于stack exchange,提问作者clifredd
相关产品推荐
相关产品推荐

