2

我想每天将我的用户与他/她社区中的不同用户进行匹配。目前,我使用这样的代码:

@matched_user = User.near(@user).order("RANDOM()").first

但我希望每天都有一个不同的@matched_user。我无法在 Stack 或 API 中找到任何让我了解如何做到这一点的东西。我觉得它应该比使用 cron 执行 rake 任务更简单。(我在 postgres 上。)

4

3 回答 3

4

每当我发现自己渴望共享“内存”或瞬态状态时,我都会对自己说“这就是(分布式)缓存的发明目的”。

@matched_user = Rails.cache.fetch(@user.cache_key + '/daily_match', expires_in: 1.day) {
  User.near(@user).order("RANDOM()").first
}

注意:虽然为缓存条目指定 TTL 会告诉 Rails/缓存系统尝试在给定的时间范围内保持该值,但不能保证它。特别是,积极尝试回收内存的缓存可能会在其所需expires_in时间之前使条目过期。

对于这个特定的用例,这应该没什么大不了的,但是在业务/域逻辑需要定期生成持久值的情况下,您确实必须将其考虑到您的数据库中。

于 2013-10-22T06:38:55.233 回答
1

使用 PostgreSQL 的SETSEED功能怎么样?我用日期播种,这样种子每天都会改变,但一天之内,种子会保持一致。:

User.connection.execute "SELECT SETSEED(#{Date.today.strftime("%y%d%m").to_i/1000000.0})"
@matched_user = User.near(@user).order("RANDOM()").first

您可能希望在使用后播种一个随机值,以便将来对 random 的任何调用都不会有偏差:

random = User.connection.execute("SELECT RANDOM()").to_a.first["random"]
# Same code as above:
User.connection.execute "SELECT SETSEED(#{Date.today.strftime("%y%d%m").to_i/1000000.0})"
@matched_user = User.near(@user).order("RANDOM()").first
# Use random value before seed to make new seed:
User.connection.execute "SELECT SETSEED(#{random})"
于 2013-10-22T06:19:41.137 回答
1

为了便于阅读,我将这些步骤分成了不同的部分。您可以稍后优化查询。

1)查找到今天早上的所有用户记录。这样计数就会冻结。

usrs_till_today_morning = User.where("created_at <?", DateTime.now.in_time_zone(Time.zone).beginning_of_day)

2)提取所有ID

user_ids = usr_till_today_morning.pluck(:id)

3)今天日期将是一个范围(1..30),但将在一天中保持不变。

day_today = Time.now.day

4)当天选择同一个ID

todays_user_id = user_ids[day_today % user_ids.count]

@matched_user =  User.find(todays_user_id)

所以它会通过全天保持相同的记录来给你随机的用户记录!!

于 2013-10-22T06:28:24.230 回答