0

私はPython2.7とwebapp2フレームワークでappengineを使用しています。ndb.modelを使用していません。

私は次のモデルを持っています:

class Story(db.Model);
    name = db.StringProperty()

class UserProfile(db.Model):
    name = db.StringProperty()
    user = db.UserProperty()

class Tracking(db.Model):
   user_profile = db.ReferenceProperty(UserProfile)
   story = db.ReferenceProperty(Story)
   upvoted = db.BooleanProperty()
   flagged = db.BoolenProperty()

ユーザーはストーリーに賛成またはフラグを立てることができますが、1回だけです。そこで、上記のモデルを思いつきました。ここで、ユーザーがupvoteリンクをクリックすると、データベースで、ユーザーがまだ投票していないかどうかを確認しようとします。したがって、次のことを実行しようとします。

  1. IDを次のように使用してユーザーインスタンスを取得しますup = db.get(db.Key.from_path('UserProfile', uid))

  2. 次に、次のようにストーリーインスタンスを取得しますs_ins = db.get(db.Key.from_path('Story', uid))

  3. Tracking次に、これら2つに基づくが存在するかどうかを確認します。存在する場合は投票を許可しません。存在しない場合は、投票してTrackingインスタンスを更新します。

とのid( )を指定してインスタンスをフェッチする最も便利な方法は何ですか?Trackingdb.key().id()user_profilestory

ユーザープロファイルIDとストーリーIDを指定してモデルを保存する最も便利な方法は何ですか?Tracking

追跡を実装するためのより良い方法はありますか?

4

2 に答える 2

1

キーのリストを使用して追跡を試すことができますが、トラック/ユーザー/ストーリーに個別のエントリを設定することはできません。

class Story(db.Model);
  name = db.StringProperty()

class UserProfile(db.Model):
  name = db.StringProperty()
  user = db.UserProperty()

class Tracking(db.Model):
  story = db.ReferenceProperty(Story)
  upvoted = db.ListProperty(db.Key)
  flagged = db.ListProperty(db.Key)

したがって、ユーザーが特定のストーリーに賛成したかどうかを確認したい場合は、次のようにします。

Tracking.all().filter('story =', db.Key.from_path('Story', uid)).filter('upvoted =', db.Key.from_path('UserProfile', uid)).get(keys_only=True)

ここでの唯一の問題は、賛成/フラグ付きリストのサイズが大きくなりすぎないことです(制限は5000だと思います)。したがって、これを管理するクラスを作成する必要があります(つまり、賛成に追加する場合)。 / flagedリスト、Xエントリが存在するかどうかを検出し、存在する場合は、追加の値を保持するために新しい追跡オブジェクトを開始します)。また、これをトランザクション化する必要があり、HRを使用すると、1秒あたり1回の書き込みのしきい値があります。これは、予想されるユースケースに応じて問題になる場合とそうでない場合があります。書き込みしきい値を回避する方法は、プルキューを使用して賛成票/フラグを実装し、必要に応じて追跡オブジェクトをプルしてバッチ更新するcronジョブを作成することです。

この方法には長所と短所があります。最も明白な短所は、私が今リストしたものです。しかし、プロはそれだけの価値があるかもしれません。単一のリスト(またはストーリーの人気度によっては複数)から、ストーリーに賛成/フラグを立てたユーザーの完全なリストを取得できます。データストアへのクエリがはるかに少ないユーザーの完全なリストを取得できます。この方法では、ストレージ、インデックス、メタデータのスペースも少なくて済みます。さらに、ユーザーを追跡オブジェクトに追加する方が安価です。新しいオブジェクトを書き込む+プロパティごとに2回の書き込みを行う代わりに、オブジェクトに対して1回の書き込み+リストへのエントリに対して2回の書き込みを請求します(9回の書き込みと3回の書き込み)。既存の追跡されたストーリーにユーザーを追加する場合、または追跡されていないストーリーの場合は9対7)

于 2012-09-27T18:20:47.827 に答える
0

あなたが提案することは合理的に聞こえます。

トラッキングにAppEngineで生成されたキーを使用しないでください。ストーリー/ユーザーの組み合わせは一意である必要があるため、ストーリー/ユーザーの組み合わせとして独自のキーを作成します。何かのようなもの

tracking = Tracking.get_or_insert(str(story.id) + "-" + str(user.id), **params)

ストーリー/ユーザーを知っている場合は、いつでもキー名で追跡を取得できます。

于 2012-09-27T02:08:40.883 に答える