Google App Engine(Python)でこれを行う方法:
SELECT COUNT(DISTINCT user) FROM event WHERE event_type = "PAGEVIEW"
AND t >= start_time AND t <= end_time
ロングバージョン:
ページビューなどのイベントを生成するユーザーを含むPythonGoogleAppEngineアプリケーションがあります。特定の期間に、ページビューイベントを生成したユニークユーザーの数を知りたいです。私が最も興味を持っている期間は1週間であり、そのようなイベントは1週間に約100万件あります。これをcronジョブで実行したいと思います。
私のイベントエンティティは次のようになります。
class Event(db.Model):
t = db.DateTimeProperty(auto_now_add=True)
user = db.StringProperty(required=True)
event_type = db.StringProperty(required=True)
SQLデータベースで、私は次のようなことをします
SELECT COUNT(DISTINCT user) FROM event WHERE event_type = "PAGEVIEW"
AND t >= start_time AND t <= end_time
最初に発生するのは、すべてのPAGEVIEWイベントを取得し、重複するユーザーを除外することです。何かのようなもの:
query = Event.all()
query.filter("t >=", start_time)
query.filter("t <=", end_time)
usernames = []
for event in query:
usernames.append(event.user)
answer = len(set(usernames))
ただし、これは最大1000のイベントしかサポートしないため、機能しません。次に私に起こることは、1000のイベントを取得することです。そして、それらがなくなると、次の1000を取得します。ただし、1,000のクエリを実行し、100万のエンティティを取得するには、リクエストの制限時間である30秒以上かかるため、これも機能しません。
次に、重複をより速くスキップするために、ユーザーごとに注文する必要があると思いました。しかし、私はすでに不等式 "t> = start_time AND t <= end_time"を使用しているため、これは許可されていません。
これは30秒以内に達成できないことは明らかであるため、断片化する必要があります。しかし、個別のアイテムを見つけることは、サブタスクにうまく分割されていないようです。私が考えることができる最善の方法は、すべてのcronジョブ呼び出しで、1000のページビューイベントを見つけて、それらから個別のユーザー名を取得し、それらをChardのようなエンティティに配置することです。それは次のように見えるかもしれません
class Chard(db.Model):
usernames = db.StringListProperty(required=True)
したがって、各フダンソウには最大1000のユーザー名が含まれますが、重複が削除された場合はそれより少なくなります。約16時間後(これで問題ありません)、すべてのチャードができて、次のようなことができます。
chards = Chard.all()
all_usernames = set()
for chard in chards:
all_usernames = all_usernames.union(chard.usernames)
answer = len(all_usernames)
うまくいくように見えますが、美しい解決策とは言えません。また、十分なユニークユーザーがいる場合、このループには時間がかかりすぎる可能性があります。誰かがより良い提案を思い付くと期待してテストしていません。したがって、このループが十分に高速であることが判明した場合はそうではありません。
私の問題に対するより良い解決策はありますか?
もちろん、このユニークなユーザー数はすべてGoogle Analyticsで簡単に達成できますが、私はアプリケーション固有の指標のダッシュボードを作成しており、これが多くの統計の最初のものになることを意図しています。