ActiveRecord や SQL を使用して補完を見つけようとしています。
それぞれに2つの関連フィールドがある「注釈」のコレクションがあります。
- 注釈を実行したユーザーに対応する session_datum_id。Null は、まだ実行されていないことを意味します。
- 注釈が「about」である投稿を表す post_id。null にすることはできません。
post_id ごとに複数の注釈が存在する可能性があります。
2 つの制約を満たすアノテーションを効率的に見つけたいと考えています。
- session_datum_id がヌルです。これは、この特定の注釈がまだ実行されていないことを意味します。
- arg として渡された session_datum は、同じ post_id を持つ別のアノテーションをまだ実行していません。
これは、DB の外部で結合を行う非常に単純なバージョンです。このユーザーがすでに実行したすべての注釈を検索し、まだ実行する必要がある注釈の完全なリストからそれらの post_ids を削除します。次に、結果のリストからランダムに選択します。
def self.random_empty_unseen(session_datum)
mine = where('session_datum_id = ?', session_datum)
elligible = where('session_datum_id IS NULL')
mine.each do |i|
elligible.each do |j|
if (i.post_id == j.post_id)
elligible.delete(j)
end
end
end
elligible[rand(elligible.count)]
end
注釈のリストが大きくなると、これはひどく行き詰まります。適切な注釈をランダムに選択し、ユーザーが既にそれを実行したかどうかを確認する確率的アルゴリズムを想像できます (そうであれば再試行します) が、それが機能しない退化したケースがあります。(多数の注釈があり、ユーザーはそのうちの 1 つを除いてすべてを実行しました。)
おそらくNOT EXISTSを使用して、これに対するクローズドフォームクエリはありますか?