【问题标题】:Rails - listing most active profile based on number of posts, commentsRails - 根据帖子、评论的数量列出最活跃的个人资料
【发布时间】:2016-05-04 08:18:12
【问题描述】:

个人资料可以创建帖子。 个人资料可以对帖子发表评论。 权重:post = 1,comment = 1。

我需要根据上个月内帖子、cmets 的综合权重列出人员。

我尝试过的是:

profiles = Profile.find(:all, :include => [:posts, :comments], :conditions => ["posts.created_at > ? or comments.created_at > ?", 1.month.ago, 1.month.ago], :group => "profiles.id", :group => 'profiles.id, posts.id, comments.id', :limit => 5)

sql = "SELECT DISTINCT profiles.id, count(posts.id) + count(comments.id) as pcount FROM profiles LEFT OUTER JOIN posts ON posts.profile_id = profiles.id LEFT OUTER JOIN comments ON comments.profile_id = profiles.id WHERE (posts.created_at > '#{1.month.ago}' and posts or comments.created_at > '#{1.month.ago}') GROUP BY profiles.id Order by pcount"
profiles = ActiveRecord::Base.connection.execute(sql)

【问题讨论】:

  • 您的个人资料表中可以有两个属性,:cmets_count & :posts_count,并且每次用户写帖子或评论时,您可以使用 Rails 回调来增加这些值。
  • 在这种情况下,我们无法读取发布或评论的时间。我需要最近一个月的顶级贡献者名单。

标签: ruby-on-rails rails-postgresql


【解决方案1】:

我建议我们在以created_at 日期为条件的两个表上LEFT JOIN,并将每个独立的非NULL 值的总数计算为一个名为total_weight 的新字段:

profiles = Profile.joins("LEFT JOIN posts ON posts.profile_id = profiles.id AND posts.created_at > ? LEFT JOIN comments ON comments.profile_id = profiles.id AND comments.created_at > ?", 1.month_ago, 1.month_ago).group("profiles.id").select("profiles.*, sum(posts.id IS NOT NULL) + sum(comments.id IS NOT NULL) as total_weight")

您可以在orderhaving 子句中使用"total_weight",并且可以在结果中引用它:profiles.first.total_weight

我会考虑在profiles 的新列中保留各自的计数或总计数,以使此查询更快、更易于维护。您可以有一个任务每天运行以在每个配置文件上更新它,这样必须获取记录的控制器不必每次都启动此计算。

【讨论】:

  • 在这种情况下额外的字段将无济于事,因为我们考虑了发布/评论的时间。
  • 那么建议加入怎么办?
  • 如果你有一个离线任务,比如说,每天运行一次,以更新它们,那么关于额外字段的要点。我们在我们的应用程序的几个地方这样做;例如,如果对象处于一组其他状态并且 2 周未更新,则将状态列更新为“隐藏”。这样,在我们的主登录页面上运行的查询就不必比较日期,这很慢,而只需与离线更新的索引状态列进行比较。
【解决方案2】:

使用列month, 'comments_count', 'posts_count','profile_id' 创建一个模型Activities,这样,

在你的profile.rb,你有

has_many :activities

activity.rb,你有

belongs_to :profile

在每个月底使用whenever gem,运行一项计算这些数字并为每个用户添加值的作业。

优点:

  1. 您可以统计每个月的所有个人资料活动。
  2. 这会缓存您的输出并大大简化您的查询。你只需要:profile.activities.where(month: Date.today.month - 1.month)

PS:你可以改进查询

缺点: 1.随着时间的推移和个人资料的增加,将难以维护。

如果你只想统计上个月的数据,这个问题很容易解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 2016-11-07
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 2017-09-19
    相关资源
    最近更新 更多