15

私の質問は、ndb での 1 対多の関係のモデル化についてです。これは、(少なくとも) 2 つの異なる方法で実行できることを理解しています: 繰り返しプロパティまたは「外部キー」です。以下に小さな例を作成しました。基本的に、任意の数のタグを持つことができる記事があります。タグを削除することはできますが、追加した後に変更することはできないと仮定しましょう。また、トランザクションの安全性について心配していないと仮定しましょう。

私の質問は、これらの関係をモデル化するための好ましい方法は何ですか?

私の考慮事項:

  • アプローチ (A) では、記事に追加されるタグごとに 2 回の書き込み (記事用とタグ用) が必要ですが、アプローチ (B) では 1 回の書き込み (タグのみ) のみが必要です。
  • アプローチ (A) では、アーティクルのすべてのタグを取得するときに ndb のキャッシュ メカニズムを利用しますが、アプローチ (B) の場合は、クエリが必要です (さらに、いくつかのカスタム キャッシュ)。

ここで見逃しているもの、考慮すべきその他の考慮事項はありますか?

どうもありがとうございました。

例 (A):

class Article(ndb.Model):
    title = ndb.StringProperty()
    # some more properties
    tags = ndb.KeyProperty(kind="Tag", repeated=True)

    def create_tag(self):
        # requires two writes
        tag = Tag(name="my_tag")
        tag.put()
        self.tags.append(tag)
        self.put()

    def get_tags(self):
        return ndb.get_multi(self.tags)

class Tag(ndb.Model):
    name = ndb.StringProperty()
    user = ndb.KeyProperty(Kind="User") #  User that created the tag
    # some more properties

例(B):

class Article(ndb.Model):
    title = ndb.StringProperty()
    # some more properties

    def create_tag(self):
        # requires one write
        tag = Tag(name="my_tag", article=self.key)
        tag.put()

    def get_tags(self):
        # obviously we could cache this query in memcache
        return Tag.gql("WHERE article :1", self.key)

class Tag(ndb.Model):
    name = ndb.StringProperty()
    article = ndb.KeyProperty(kind="Article")
    user = ndb.KeyProperty(Kind="User") #  User that created the tag
    # some more properties
4

3 に答える 3

6

Structured Properties https://developers.google.com/appengine/docs/python/ndb/properties#structuredの使用について、以下をご覧になりましたか。Contactとについての短い議論Addresseは、あなたの問題を単純化するかもしれません。https://developers.google.com/appengine/docs/python/ndb/queries#filtering_structured_propertiesもご覧ください。議論は非常に短いです。

また、結合が許可されていないという事実を見越して、オプションAはより良く見えます。

于 2012-12-18T16:48:30.030 に答える
1

ほとんどの状況では、アプローチ (A) が優先されます。タグを追加するには 2 回の書き込みが必要ですが、これはおそらくタグを読み取るよりもはるかに少ない頻度です。膨大な数のタグがない限り、それらはすべて、繰り返される Key プロパティに収まる必要があります。

おっしゃったように、タグをキーでフェッチする方が、クエリを実行するよりもはるかに高速です。また、タグの名前とユーザーのみが必要な場合は、 をUser親キーNameとして、 をタグの ID としてタグを作成できます。

User -> Name -> Tag

このタグを作成するには、次を使用します。

tag = Tag(id=name, parent=user, ...)
article.tags.push(tag)
ndb.put_multi([tag, article])

次に、タグを取得すると、

for tag in article.tags:
    user = tag.parent()
    name = tag.id()

次に、保存した各キーにArticle.tagsは、ユーザー キーとTag名前が含まれます。これにより、これらの値を取得するために を読み込む必要がなくなりTagます。

于 2015-09-18T23:00:45.137 に答える