如何跟踪用户在 X 天内每天访问该网站?

发布于 2024-07-22 21:03:35 字数 333 浏览 3 评论 0原文

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

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

你能做得更简单吗?

There is a new badge on Stack Overflow. The "woot" badge is awarded to users visited the site each day for 30 days. How can you implement a feature like this? How can you track that a user visited the site each day for X days in the simplest way?

I thought of having two fields--one for the timestamp of the last login, and another to count the days on user continuously visited the site. The logic is to first set the counter to 1, and store the time of login as well. On the very next login, check if since the last login no more than one day past, and increment the counter, or set it back to 1. And then update the timestamp field to the current date.

Can you do it simpler?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

岁月苍老的讽刺 2024-07-29 21:03:35

您确实需要有一个 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 )
    ...

请原谅我的Python技能,我是一名学者和首次网站用户)

每个 无法使用一个变量完成此任务。 我确信有人可以写出清晰的论据来证明这一事实。

You do need to have a cookie, since people might not log in every day -- for example because they are logged in automatically for 2 weeks, or because they are on your site doing things non-stop without sleep and lunch for 50 hours :) You probably actually want to count when user accesses the site.

Now, one could theoretically record every access and perform database queries, as was suggested above, but you might think (as I do) that it strikes the wrong balance between usefulness and privacy+simplicity.

The algorithm you specified is deficient in an obvious way: since you store only whole number of days, you miss the user who logs in and out every 12 hours (your algorithm would keep the count of days as 1)

Here's the solution that I find to be cleanest with two date fields per user, in a kind of self-explanatory non-object oriented 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 )
    ...

(Please forgive my Pythonic skills, I'm an academic and first-time site user)

You cannot do this task with one variable. I'm sure somebody can write a clean argument proving this fact.

横笛休吹塞上声 2024-07-29 21:03:35

实际上,如果会员的访问位于 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

Actually, if the Member's visits are in a SQL database, you can do the whole thing with a single SQL query. This is also probably faster than schlepping all of the data over to a client program to check it anyway:

/*
    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
盗梦空间 2024-07-29 21:03:35

使用时间戳跟踪数据库中的每次访问(无论如何您可能已经这样做了)。 然后创建一条sql语句并将结果按天分组,同时统计当天的访问次数。 近30天内不允许有0日访问...

Track each visit in your database with a timestamp (which you probably already do anyway). Then create an sql statement and group the result by day, while you count the number of visits that day. In the period of the last 30 days, it's not allowed to have a 0-visit day...

慢慢从新开始 2024-07-29 21:03:35

我赞同罗普斯塔的做法。 用户统计信息(例如登录时间等)通常可以在数据库中获得。 我们需要从现有数据中得出某些事实。 因此,我不想为每次访问设置一个计数器并递增内容,而是更喜欢在用户登录数据上运行并发布当天结果的批处理作业。

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

I second ropstah's approach. User statistics like login time etc are usually available in the database. We need to derive certain facts out of the available data. So rather than having a counter for each visit and incrementing stuff, I would prefer a batch job that runs on the user login data and publish the results for that day.

But once a user "woot"ed, you might want to stop computing "woot"ness for that user.
Else, there is a chance of the user getting "wooted" every day, till a no-login day is encountered. (but this is a minor issue).

逆夏时光 2024-07-29 21:03:35

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

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

我创建特定模式来保存此类信息的唯一情况是,由于数据量或其复杂性,所需的计算时间太长。

If this is the only thing you want to log, then maybe that's a good solution. However, I like to keep logic and the logging separate, both to increase the amount of raw information at my disposal, as well as allow tweaking of logic without breaking existing data.

In this case, I would log every visit or every action (depending on requirements/space/etc), and then write a sproc or a method somewhere which inspected the data and returned true (matches criteria for badge) or false (doesn't match criteria).

The only case where I would create a specific schema to hold information like that was if the calculations required took far too long, either because of the amount of data or the complexity thereof.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文