googleappengine:更好的查询方式

2024-09-28 18:54:07 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有RootEntityAEntity(RootEntity的子级),BEntity(RootEntity的子级)。你知道吗

class RootEntity(ndb.Model):
    rtp = ndb.StringProperty()

class AEntity(ndb.Model):
    ap = ndb.IntegerProperty()

class BEntity(ndb.Model):
    bp = ndb.StringProperty()

因此,在不同的处理程序中,我需要获得具有特定祖先的benty实例(AEntity实例)。你知道吗

有一个我的查询:BEntity.query(ancestor = ndb.Key("RootEntity", 1, "AEntity", AEntity.query(ancestor = ndb.Key("RootEntity", 1)).filter(AEntity.ap == int(some_value)).get().key.integer_id()))

如何优化此查询?做得更好,可能不那么复杂?你知道吗

升级版:

此查询是带有@ndb.transactional装饰器的函数的一部分。你知道吗


Tags: 实例keymodelqueryclassapndb子级
2条回答

不应使用实体组来表示实体关系。你知道吗

Entity groups have a special purpose:定义事务的范围。它们使您能够以事务方式更新多个实体,只要它们是同一实体组的一部分(新的XG transactions稍微放宽了这个限制)。它们还允许您在事务中使用查询(不可通过XG事务使用)。你知道吗

实体组的缺点是它们的更新限制为1次写入/秒。你知道吗

在你的情况下,我的建议是使用不同的实体,并在它们之间作参考。引用应该是被引用实体的键,因为这是类型安全的。你知道吗

关于查询的简单性:不幸的是,GAE不支持连接或引用(多实体)查询,所以您仍然需要将多个查询组合在一起(就像您现在所做的那样)。你知道吗

祖先查询有一种互通有无的关系。它们处理起来更加冗长和混乱,但是您可以获得更好的数据结构和查询的一致性。你知道吗

为了简化这一点,如果处理程序知道要获取的BEntity,只需传递key.urlsafe()编码键,它已经对所有祖先信息进行了编码。你知道吗

如果这不可能,请尝试重新构造数据。由于这些对象都是同一祖先,因此它们属于同一实体组,因此最多每秒可以为该实体组中的对象插入/更新~1次。如果您需要更高的吞吐量或不需要一致的祖先查询,那么请尝试使用ndb.KeyProperty将实体链接到父级引用,而不是作为祖先。然后您只需要查询单个父级,而不需要查询父级和父级的父级。你知道吗

您还应该尽可能尝试使用ID,这样就可以避免按属性筛选数据存储中的实体,而只按ID引用它们:

BEntity.query(ancestor = ndb.Key("RootEntity", 1, "AEntity", int(some_value)))

这里,int(some_value)是创建对象时使用的AEntity的整数ID。只需确保手动创建/使用的ID在共享同一父级的模型的所有实例中都是唯一的。

编辑: 为了澄清,我的最后一个例子应该更清楚,因为我建议重新构造数据,以便int(some_value)用作AEntity的整数ID,而不是将is作为实体的一个单独属性存储—当然,如果可能的话。在给定的示例中,对具有给定整型字段值int(some_value)AEntity对象执行查询,并使用get()执行-这意味着您将始终期望该整型ID返回一个值,从而使其成为用作该对象键的整型ID的很好的候选对象,从而消除了查询的需要。你知道吗

相关问题 更多 >