2

StatisticStore次のように定義されたモデルがあります。

class StatisticStore(ndb.Model):
  user = ndb.KeyProperty(kind=User)
  created = ndb.DateTimeProperty(auto_now_add=True)
  kind = ndb.StringProperty()
  properties = ndb.PickleProperty()

  @classmethod
  def top_links(cls, user, start_date, end_date):
    '''
    returns the user's top links for the given date range
    e.g.
    {'http://stackoverflow.com': 30,
     'http://google.com': 10,
     'http://yahoo.com': 15}
    '''
    stats = cls.query(
      cls.user == user.key,
      cls.created >= start_date,
      cls.created <= end_date,
      cls.kind == 'link_visited'
    )
    links_dict = {}
    # generate links_dict from stats
    # keys are from the 'properties' property
    return links_dict

1 日あたりAggregateStatisticStoreの集計を格納するモデルが必要です。StatisticStore1 日に 1 回生成される可能性があります。何かのようなもの:

class AggregateStatisticStore(ndb.Model):
  user = ndb.KeyProperty(kind=User)
  date = ndb.DateProperty()
  kinds_count = ndb.PickleProperty()
  top_links = ndb.PickleProperty()

したがって、次のことが当てはまります。

start = datetime.datetime(2013, 8, 22, 0, 0, 0)
end = datetime.datetime(2013, 8, 22, 23, 59, 59)

aug22stats = StatisticStore.query(
  StatisticStore.user == user,
  StatisticStore.kind == 'link_visited',
  StatisticStore.created >= start,
  StatisticStore.created <= end
).count()
aug22toplinks = StatisticStore.top_links(user, start, end)

aggregated_aug22stats = AggregateStatisticStore.query(
  AggregateStatisticStore.user == user,
  AggregateStatisticStore.date == start.date()
)

aug22stats == aggregated_aug22stats.kinds_count['link_visited']
aug22toplinks == aggregated_aug22stats.top_links

taskqueue API で cronjob を実行することだけを考えていました。タスクは、AggregateStatisticStore毎日の を生成します。しかし、メモリの問題が発生するのではないかと心配していましたか? ユーザーStatisticStoreごとに多くのレコードがある可能性があります。

また、top_linksプロパティの種類は物事を少し複雑にします。集約モデルにプロパティを含めることが最善の方法であるかどうかはまだわかりません。そのプロパティの提案は素晴らしいでしょう。

StatisticStore最終的には、最大 30 日前までの記録のみを保持したいと考えています。レコードが 30 日以上経過している場合は、集計 (および削除) する必要があります。スペースを節約し、視覚化のためのクエリ時間を改善します。

編集: a が記録されるたびにStatisticStore、適切なレコードを作成/更新しますAggregateStatisticStore。そうすれば、cronjob がしなければならないのはクリーンアップだけです。考え?

4

3 に答える 3

1

ええ、これには mapreduce が適しています。または、「バックエンド」(現在はモジュール) インスタンスを使用して cron ジョブを実行することもできます。これにより、メモリの問題とジョブの長さの問題が軽減される場合があります。

別のアプローチとして、集計を書き込み時間に移動することもできます。これはユーザーごとであるため、そのようにして多くの作業を省くことができる場合があります。AggregateStatisticStore が 1 日単位の場合、日付には DateProperty 以外のものを使用することをお勧めします。もちろん、DateProperty は機能しますが、int が単に「ある日以来」であるこの種のことには、IntegerProperty を使用する方が簡単だと思います。

于 2013-08-22T14:02:46.153 に答える
0

データの集計に多少関連しています。

StatisticStoreandを親としてAggregateStatisticStore持つように変更します。user.keyこれはuser = ndb.KeyProperty(kind=User)、各モデルから削除し、 でそれぞれを作成しparent = user.keyて使用parent = user.keyすることを意味しquery()ます。NDB は、同じ親を持つデータの集約に適しています。

于 2013-08-22T21:00:44.597 に答える
0

AggregateStatisticScoreが互いに独立している場合、 MapReduce を使用する必要はありません。ユーザーごとにループを実行できる場合は、ユーザーごとにタスクキュー プロセスを実行し、単一のレコードを書き込みます。これは事実上、「マップ」フェーズにすぎません。

より多くの並列タスクにさらに分割できる場合は、さらに多くのタスクキュー プロセスを作成します。それを「並列化」!

于 2013-08-22T21:11:00.610 に答える