7

Stack Overflow に新しいバッジがあります。「woot」バッジは、30 日間毎日サイトにアクセスしたユーザーに付与されます。このような機能をどのように実装できますか? ユーザーが毎日 X 日間サイトにアクセスしたことを最も簡単な方法で追跡するにはどうすればよいでしょうか?

最後にログインしたときのタイムスタンプ用のフィールドと、ユーザーがサイトに継続的にアクセスした日数をカウントするための 2 つのフィールドを用意することを考えました。ロジックは、最初にカウンターを 1 に設定し、ログイン時刻も保存することです。次回のログイン時に、前回のログインから 1 日以上経過していないかどうかを確認し、カウンターをインクリメントするか、1 に戻します。次に、タイムスタンプ フィールドを現在の日付に更新します。

もっと簡単にできますか?

4

5 に答える 5

4

人々は毎日ログインするとは限らないため、Cookie が必要です。 ) 実際には、ユーザーがいつサイトにアクセスしたかをカウントしたいでしょう。

理論的には、上記で提案したように、すべてのアクセスを記録してデータベース クエリを実行することもできますが、(私がそうであるように) 有用性とプライバシー + シンプルさのバランスが間違っていると思うかもしれません。

指定したアルゴリズムには明らかな欠陥があります。整数の日数のみを保存するため、12 時間ごとにログインおよびログアウトするユーザーを見逃すことになります (アルゴリズムは日数を 1 として保持します)。

これは、一種の自明の非オブジェクト指向 Python で、ユーザーごとに2 つの日付フィールドで最もクリーンであることがわかったソリューションです。

# user.beginStreak----user.lastStreak is the last interval when 
# user accessed the site continuously without breaks for more than 25h 

def onRegister (user):
    ...
    user.beginStreak = user.endStreak = time() # current time in seconds 
    ...

def onAccess (user): 
    ...
    if user.endStreak + 25*60*60 < time():
        user.beginStreak = time()
    user.endStreak = time()
    user.wootBadge = ( user.endStreak-user.beginStreak > 30*24*60*60 )
    ...

(私のPythonicスキルを許してください。私はアカデミックで初めてのサイトユーザーです)

このタスクは、 1 つの変数では実行できません。誰かがこの事実を証明する明確な議論を書くことができると確信しています.

于 2009-05-31T20:41:33.420 に答える
2

実際、メンバーの訪問が SQL データベースにある場合、単一の SQL クエリですべてを実行できます。これはおそらく、すべてのデータをクライアント プログラムに転送してチェックするよりもおそらく高速です。

/*
    Find all members who visited at least once every day
  for 30 or more days.  --RBarryYoung, 2009-05-31
*/
;WITH
  cteVisitDays as (
    Select
      MemberID
    , DATEDIFF(dd,'2008-06-01',VisitTime) as VisitDay
     From tblMembersLog
     Where Not Exists( Select * From tblMemberTags T
    Where T.MemberID = tblMembersLog.MemberID
     And T.TagName = 'WOOT!' )
     Group By MemberID
        , DATEDIFF(dd,'2008-06-01',VisitTime)
    )
, cteVisitRunGroups as (
    Select 
      MemberID
    , VisitDay - Row_Number() Over(
            Partition By MemberID
            Order By VisitDay
        ) as RunGrouping
     From cteVisitDays
     )
SELECT Distinct
  MemberID
 From cteVistRunGroups
 Group By MemberId, RunGrouping
 Having COUNT(*) >= 30
于 2009-05-31T20:07:14.440 に答える
1

タイムスタンプを使用して、データベース内の各訪問を追跡します (おそらく既に行っていることでしょう)。次に、SQL ステートメントを作成し、その日の訪問数を数えながら、結果を日ごとにグループ化します。過去 30 日間に、0 訪問日を設定することはできません...

于 2009-05-31T18:43:12.847 に答える
1

私は2番目のropstahのアプローチです。ログイン時間などのユーザー統計は通常、データベースで利用できます。利用可能なデータから特定の事実を導き出す必要があります。したがって、訪問ごとにカウンターを作成してインクリメントするのではなく、ユーザーのログイン データで実行され、その日の結果を公開するバッチ ジョブを使用したいと考えています。

しかし、ユーザーが一度 "woot" すると、そのユーザーの "woot"ness の計算を停止したい場合があります。そうしないと、ログインなしの日が発生するまで、ユーザーが毎日「だまされて」しまう可能性があります。(しかし、これは小さな問題です)。

于 2009-05-31T18:50:06.080 に答える
0

これがログに記録したい唯一のものである場合は、おそらくそれが良い解決策です。ただし、私はロジックとログを別々に保つことを好みます。どちらも、自由に使える生の情報の量を増やし、既存のデータを壊さずにロジックを微調整できるようにするためです。

この場合、すべての訪問またはすべてのアクションを (要件/スペース/などに応じて) ログに記録し、データを検査して true (バッジの基準に一致) または false (一致しない) を返す sproc またはメソッドをどこかに記述します。一致基準)。

そのような情報を保持するために特定のスキーマを作成する唯一のケースは、データの量または複雑さのために、必要な計算に時間がかかりすぎる場合でした。

于 2009-05-31T18:47:50.187 に答える