7

Stack Overflow 上有一个新徽章。“ woot ”徽章授予在 30 天内每天访问该网站的用户。如何实现这样的功能?您如何以最简单的方式跟踪用户在 X 天内每天访问该网站的情况?

我想有两个字段——一个用于上次登录的时间戳,另一个用于计算用户连续访问该站点的天数。逻辑是首先将计数器设置为1,并存储登录时间。在下一次登录时,检查自上次登录以来是否不超过一天,并增加计数器,或将其设置回 1。然后将时间戳字段更新为当前日期。

你能做得更简单吗?

4

5 回答 5

4

您确实需要一个 cookie,因为人们可能不会每天都登录- 例如因为他们会自动登录 2 周,或者因为他们在您的网站上不停地做事 50 小时不睡觉和吃午饭: ) 您可能实际上想要计算用户访问该站点的时间。

现在,理论上可以记录每次访问并执行数据库查询,正如上面建议的那样,但你可能会认为(就像我一样)它在有用性和隐私+简单性之间取得了错误的平衡。

您指定的算法明显存在缺陷:由于您仅存储整数天数,因此您错过了每 12 小时登录和注销的用户(您的算法会将天数保持为 1)

这是我发现每个用户有两个日期字段的最干净的解决方案,在一种不言自明的非面向对象的 Python 中:

# 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 技能,我是一名学术和首次站点用户)

你不能用一个变量来完成这项任务。我相信有人可以写一个干净的论据来证明这一事实。

于 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-visit day...

于 2009-05-31T18:43:12.847 回答
1

我第二个 ropstah 的方法。登录时间等用户统计信息通常在数据库中可用。我们需要从可用数据中得出某些事实。因此,与其为每次访问设置一个计数器并增加内容,我更喜欢在用户登录数据上运行并发布当天结果的批处理作业。

但是,一旦用户“吸引”了用户,您可能希望停止为该用户计算“吸引”。否则,用户每天都有可能被“吸引”,直到遇到无登录日。(但这是一个小问题)。

于 2009-05-31T18:50:06.080 回答
0

如果这是您想要记录的唯一内容,那么也许这是一个很好的解决方案。但是,我喜欢将逻辑和日志分开,既可以增加我可以使用的原始信息量,也可以在不破坏现有数据的情况下调整逻辑。

在这种情况下,我会记录每次访问或每次操作(取决于要求/空间/等),然后在某处编写一个存储过程或方法来检查数据并返回 true(匹配徽章标准)或 false(不匹配标准)。

我会创建一个特定的模式来保存这样的信息的唯一情况是,如果所需的计算时间太长,要么是因为数据量大,要么是因为数据的复杂性。

于 2009-05-31T18:47:50.187 回答