Google NDB:从实体读取子实体的最佳方式,重复属性与常规查询?

had*_*are 5 google-app-engine app-engine-ndb google-cloud-datastore

假设我有这个非常简单的父/子relatiosnship (任何Answer类实例总是有Question父母):

class Answer(ndb.Model):
    content = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty()

    def to_message():
        """Returns a protoRPC message object of the answer"""


class Question(ndb.Model):
    content = ndb.StringProperty()
    answers = ndb.KeyProperty(repeated = True, kind = 'Answer')

    def to_message(self):
        """Returns a protoRPC message object of the question"""
Run Code Online (Sandbox Code Playgroud)

这两种to message方法仅用于返回protoRPC对象.问题是:在我的to_message方法中,在Question类中,如果我想获取所有子Answer实例,检索它们,并使用自己的to_message方法将它们变成一个很好的rpc消息,那么它更好:

  • 迭代anwers重复的KeyProperty列表
  • 使用"父"属性上的过滤器执行查询,并迭代它输出的列表

在NDB访问方面,第一种方法似乎是最好的,但由于我们无论如何都要超过免费限制,我更想知道数据存储区在获取内容方面是否比我更有效,迭代那份清单.

编辑:原始问题实际上是一个非常简单明了的答案:第一种方式.真正的问题是,如果我必须Answer根据它们的属性过滤掉一些实体(例如timestamp):使用过滤器查询是否更好,或者迭代列表并使用条件仅收集"有趣"实体?

Her*_*sta 4

使用该模式,您不必查询任何内容,因为您已经将每个答案的键作为键列表question_entity.answers

因此,您只需使用该键获取答案即可。如果您只需一次操作即可获得所有答案,那就更好了。

list_of_answers = ndb.get_multi(question_entity.answers)
Run Code Online (Sandbox Code Playgroud)

(更多信息请参见NDB 实体和密钥

另一方面,如果您使用 in 建模该KeyProperty关系Answer

class Answer(ndb.Model):
    question = ndb.KeyProperty(Question)
    content = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty()

def to_message():
    """Returns a protoRPC message object of the answer"""
Run Code Online (Sandbox Code Playgroud)

或与祖先:

answer = Answer(parent=question_entity.key)
Run Code Online (Sandbox Code Playgroud)

在这些情况下,您应该使用普通查询来检索答案:

answers = Answer.query(Answer.question == question_entity.key)
Run Code Online (Sandbox Code Playgroud)

或祖先查询:

answers = Answer.query(ancestor = question_entity.key)
Run Code Online (Sandbox Code Playgroud)

分别。

这意味着两项工作:查询索引以及获取数据存储。总之,在这种情况下,第一种方法对于检索数据存储数据来说更便宜。