0

私のスキーマでは、以下のテストデータ生成の例で説明されているように、次のことを行うための良い方法を知りたいと思います。

削除された画像のインスタンスへの参照キーを持つお気に入りのすべてのインスタンスを逆参照します。削除した画像にリンクしているお気に入りを削除するだけです。

  • Personクラスはユーザーです

  • クラスはPictureお気に入りになることができるものです

  • このFavouriteクラスは、多対多の関係を持つLink-Modelの方法の例です。

なぜこの質問ですか? まず、ここで範囲外にならないことを願っています。次に、これが発生する可能性があるためです。次に、興味深いためです。

どのように? たとえば、ソーシャルネットワーク上に「いいね」があったり、さらに悪いことに、科学アプリケーションの注文、アカウント、無効なデータなど、人が最大数千のお気に入りを持つことができるとしましょう。私たちの例では、何らかの理由で(そしてこれらの理由が発生します)、人は死んだお気に入りのリンクをたくさん経験しています、または私は知っています、死んだお気に入りがあることを知っています。

これを行うための良い方法は何でしょうか。操作を減らし 、すべてのお気に入りを反復処理する必要はありません。ndb.get()

物事を複雑にしないようにしましょう。死んだお気に入りに苦しんでいるユーザーが1人だけであると仮定しましょう。彼はPersonのクラスと「123」のスタブされたuser_idプロパティを持っています。

次の例では、次のハンドラーとそれに対応する関数を使用できます。

import time
import sys
import logging
import random
import cgi
import webapp2

from google.appengine.ext import ndb


class Person(ndb.Expando):
    pass

class Picture(ndb.Expando):
    pass

class Favourite(ndb.Expando):
    user_id = ndb.StringProperty(required=True)
    #picture = ndb.KeyProperty(kind=Picture, required=True)
    pass

class GenerateDataHandler(webapp2.RequestHandler):

    def get(self):
        try:
            number_of_models = abs(int(cgi.escape(self.request.get('n'))))
        except:
            number_of_models = 10
            logging.info("GET ?n=parameter not defined. Using default.")
            pass
        user_id = '123' #stub
        person = Person.query().filter(ndb.GenericProperty('user_id') == user_id).get()
        if not person:
            person  = Person()
            person.user_id = user_id #Stub
            person.put()
            logging.info("Created Person instance")
        if not self._gen_data(person, number_of_models):
            return
        self.response.write("Data generated successfully")

    def _gen_data(self, person, number_of_models):
        first, last = Picture.allocate_ids(number_of_models)
        picture_keys = [ndb.Key(Picture, id) for id in range(first, last+1)]
        pictures = [] 
        favourites = []
        for picture_key in picture_keys:
            picture = Picture(key=picture_key)
            pictures.append(picture)
            favourite = Favourite(parent=person.key,
                            user_id=person.user_id, 
                            picture=picture_key
                        )
            favourites.append(favourite)
        entities = favourites
        entities[1:1] = pictures
        ndb.put_multi(entities)
        return True

class CorruptDataHandler(webapp2.RequestHandler):

    def get(self):
        if not self._corrupt_data(0.5):#50% corruption
            return
        self.response.write("Data corruption completed successfully")

    def _corrupt_data(self, n):
        picture_keys = Picture.query().fetch(99999, keys_only=True)
        random_picture_keys = random.sample(picture_keys, int(float(len(picture_keys))*n))
        ndb.delete_multi(random_picture_keys)
        return True

class FixDataHandler(webapp2.RequestHandler):

    def get(self):
        user_id = '123' #stub
        person = Person.query().filter(ndb.GenericProperty('user_id') == user_id).get()
        self._dereference(person)

    def _dereference(self, person):
    #Here if where you implement your answer

NDBデータストアの結果整合性により、ハンドラーを分離します。詳細: バックエンドNDBを使用するGAE put_multi()エンティティ

もちろん、これを投稿する前に何かを試したことを示すために、回答も投稿しています。

4

2 に答える 2

1

削除前フック​​を使用できます(実装方法についてはこちらをご覧ください)もちろん、データストアAPI(NDBのフック)の代わりにNDB APIを使用すると、これを簡単に行うことができますが、変更する必要があります。あなたがレファレンを作る方法

于 2012-12-30T04:05:45.953 に答える
1

ReferencePropertyは単なるキーであるため、削除されたPersonのキーがある場合は、それを使用してお気に入りを照会できます。

そうでなければ、簡単な方法はありません。すべてのお気に入りをフィルタリングして、無効な画像があるものを見つける必要があります。mapreduceジョブでは非常に簡単ですが、お気に入りがたくさんある場合はコストのかかるクエリになる可能性があります。

于 2012-12-26T17:11:13.750 に答える