2

自分のユーザーを、自分のコミュニティ内の別のユーザーと毎日一致させたいと考えています。現在、次のようなコードを使用しています。

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

しかし、私は毎日異なる @matched_user を持ちたいと思っています。スタックや 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

読みやすくするために、これらの手順を異なるセクションに分割しました。後でクエリを最適化できます。

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)

したがって、1 日を通して同じレコードを維持することで、ランダムなユーザー レコードが得られます!!

于 2013-10-22T06:28:24.230 に答える
1

PostgreSQLのSETSEED機能を利用してみませんか?毎日シードが変化するように、シードに日付を使用しましたが、1 日以内にシードは一貫したものになります。

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

これを使用した後にランダム値をシードして、ランダムへの将来の呼び出しが偏らないようにすることができます。

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 に答える