4

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で簡単に達成できますが、私はアプリケーション固有の指標のダッシュボードを作成しており、これが多くの統計の最初のものになることを意図しています。

4

4 に答える 4

4

SDK v1.7.4 の時点で、DISTINCT 関数が実験的にサポートされています。

参照: https://developers.google.com/appengine/docs/python/datastore/gqlreference

于 2012-12-14T12:21:27.287 に答える
1

これはおそらく実行可能な解決策です。memcache の使用にある程度依存しているため、予測できない方法でデータが削除される可能性が常にあります。買い手責任負担。

unique_visits_todayなどと呼ばれる memcache 変数があります。ユーザーがその日の最初のページビューを取得するたびに、.incr() 関数を使用してそのカウンターをインクリメントします。

これがユーザーの最初の訪問であると判断するには、ユーザーに添付されたlast_activity_dayフィールドを調べます。ユーザーがアクセスすると、そのフィールドを確認し、昨日の場合は今日に更新して、memcache カウンターを増やします。

毎日午前 0 時に、cron ジョブが memcache カウンターの現在の値を取得し、カウンターをゼロに設定しながらデータストアに書き込みます。次のようなモデルがあります。

class UniqueVisitsRecord(db.Model):
    # be careful setting date correctly if processing at midnight
    activity_date = db.DateProperty()
    event_count = IntegerProperty()

これにより、任意の日付範囲に一致するすべての UnqueVisitsRecords を簡単かつ迅速に取得し、それらのevent_countフィールドの数値を合計することができます。

于 2010-01-29T15:01:02.377 に答える
1

NDB はまだ DISTINCT をサポートしていません。私は、GAE で個別に使用できる小さなユーティリティ メソッドを作成しました。

こちらをご覧ください。http://verysimplescripts.blogspot.jp/2013/01/getting-distinct-properties-with-ndb.html

于 2013-01-24T16:42:11.143 に答える
0

Google App Engine および特定のGQLは関数をサポートしていませんDISTINCT

ただし、このブログとこのSO の質問でset説明されているように、Python の関数を使用できます。

于 2010-01-29T14:33:34.177 に答える