2

「サンプル」を収集し、サンプルのクエリと分析のためのサービスを提供するアプリ エンジンのシステムを作成しています。サンプルのデータ モデルは次のようになります。

class Sample(ndb.Model):
   category  = ndb.StringProperty()
   name      = ndb.StringProperty()
   data      = ndb.JsonProperty()
   timestamp = ndb.DateTimeProperty()
   tags      = ndb.StringProperty(repeated = True)

ご覧のとおり、サンプルごとに一連の文字列タグがあります。たとえば、次のようなものです。

['CustomerA', '2.0.5', 'featureX', 'logTypeB', ...]

基本プロパティのフィルターに基づいて、システム内のすべてのサンプルに対してクエリを実行し、必要な一連のタグを含むハンドラーがあります。注: 結果セットは非常に大きくなる可能性があるため、クエリはページング/制限をサポートしているため、一度に少しずつデータを返します。それはすべてうまくいきます。

この上にユーザー インターフェイスを配置するときに、追加のタグを入力して結果をさらにフィルター処理するためのオートコンプリート フィールドをユーザーに提示する方法が必要です。たとえば、次のタグが付いたサンプルに制限されている場合:

Sample(..., tags=['CustomerA', '2.0.5', 'featureX'])
Sample(..., tags=['CustomerA', '2.0.5', 'featureY'])
Sample(..., tags=['CustomerB', '2.0.5', 'featureX'])
Sample(..., tags=['CustomerB', '2.0.5', 'featureX'])
Sample(..., tags=['CustomerB', '2.0.5', 'featureY'])

次に、以下を含むオートコンプリートを表示したいと思います。

['CustomerA', 'CustomerB', '2.0.5', 'featureX', 'featureY']

つまり、現在の結果セットに存在するタグの一意のリストを返すことができるハンドラーが必要です。問題は、すべての結果サンプル (潜在的に非常に大きい) を反復処理し、返される一意のタグのセットを構築することなしに、App Engine でこれを行う方法がとにかく見つからないことです。

システム内のすべてのタグに対して個別のエンティティ セットを保持できますが、これでも問題は解決しません。システム内のすべてのサンプルに存在するすべてのタグをすばやく見つけることができますが、現在のフィルターを通過するサンプルのセットに限定することはできません。

これを合理的な方法で実装するために何ができるかについてのアイデアはありますか?

4

1 に答える 1

1

これを行う最善の方法は、オートコンプリート専用の別のエンティティにタグを保存することです。タグ名は一意であるため、タグをエンティティ キーとして使用できます。これは、ndb モデル フックを使用して簡単に行うことができます。例えば:

class SampleTag(ndb.Model):
  tag = ndb.StringProperty()

class Sample(ndb.Model):
  category  = ndb.StringProperty()
  name      = ndb.StringProperty()
  data      = ndb.JsonProperty()
  timestamp = ndb.DateTimeProperty()
  tags      = ndb.StringProperty(repeated = True)

  def _pre_put_hook(self):
    for tag in self.tags:
      SampleTag.get_or_insert(name=tag)

次に、SampleTag の値を使用してオートコンプリートに表示できます。

これは単なる例です。特にタグのリストが長い場合は、あまり効率的ではありません。これを改善するには、最後の保存以降に追加されたタグ (ある場合) を特定し、それらのタグのみをループする必要があります。また、非同期呼び出しを使用したり、_pre_put ルーチン全体をタスクキューに委譲したりすることもできます。これにより、モデルの put() にかかる時間が短縮されます。

また、これは削除を処理しません。タグが他の場所に存在するかどうかを事前に知ることはできないため、これは少し注意が必要です。これを行うには、cron ジョブを使用して、タグが存在するかどうかを定期的に確認します。

于 2012-06-30T21:36:03.703 に答える