查询子项 table 并按父项字段在 NDB 中排序查询结果

Query on children table and order result of a query by parent's fields at NDB

在我的模型中,我有两个 table 如下相关:

from google.appengine.ext import ndb

class Parent(ndb.Model):
    name = ndb.StringProperty()

class Child(ndb.Model):
    parent = ndb.KeyProperty(kind=Parent, indexed=True)
    name = ndb.StringProperty()

我想查询 Child table 并按父名称(升序或降序)对子记录进行排序, 我如何使用 NDB ORM 执行此操作?

尽可能不希望借助Python在代码层面完成这个过程。

总的来说@gaefan 是正确的,你不能这样做。

我只能通过 3 种方法来完成这项工作。

  1. parent 名称也必须是 parent 的密钥,然后您可以订购 Child.query().order(Child.parent).fetch()。缺点是更改 parent 的名称实际上是不可能的。您必须在所有 Child 模型和其他具有外键的模型上更改它的键和所有外键

  2. 非规范化 parent 名称作为 Child 上的字段,如下所示:

    classChild(ndb.Model): parent = ndb.KeyProperty(种类=Parent, 索引=真) 名称 = ndb.StringProperty() parent_name = ndb.StringProperty()

那么你可以Child.query().order(Child.parent_name).fetch()。不利的一面是,如果您想更改 Parent.name,则必须更新所有 children。

  1. 如果这是像 http 处理程序之类的东西,你需要 return 一页有 10 个结果之类的东西,你可以先获取按名称排序的 10 parents,然后 运行 查询所有 children 拥有 parents Child.query(namespace="test").filter(Child.parent.IN(order_parent_keys)).fetch() 之一的人(这是您在评论中建议的)。然后您必须在事后按 parent 名称订购 children。这种方法的问题是,它一次只适用于有限数量的 parent(我忘记了你可以传递多少个值给 .IN())。此外,当您 运行 超出 children 原始组 order_parent_keys 并且需要获取下一组时,分页也会变得很奇怪。

真正适合您的解决方案取决于您的数据。你有多少个 parent,你希望每个 parent 有多少个 children。此外,您尝试处理的数据量以及处理速度。

例如,如果您需要每天处理一次全部或大部分数据库,Google Dataflow 将是完美的选择。