假设我有RootEntity
,AEntity
(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
装饰器的函数的一部分。你知道吗
不应使用实体组来表示实体关系。你知道吗
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的很好的候选对象,从而消除了查询的需要。你知道吗相关问题 更多 >
编程相关推荐