在 NDB 中按父字段查询子表和排序结果

Posted

技术标签:

【中文标题】在 NDB 中按父字段查询子表和排序结果【英文标题】:Query on children table and order result of a query by parent's fields at NDB 【发布时间】:2022-01-09 03:54:02 【问题描述】:

在我的模型中,我有两个相关的表,如下所示:

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 表并按父名称(升序或降序)对子记录进行排序, 如何使用 NDB ORM 做到这一点?

我尽可能不希望这个过程在 Python 的帮助下在代码级别完成。

【问题讨论】:

你不能那样做。 @gaefan 你有关于如何将模型连接在一起来处理这种类型的排序和过滤的提议吗? @gaefan 如果创建一个父键的有序列表并在子查询中使用它们像这样Child.query(namespace="test").filter(Child.parent.IN(order_parent_keys)).fetch(),这怎么不能解决问题? 【参考方案1】:

一般@gaefan 是正确的,你不能正确地做到这一点。

我认为只有 3 种方法可以完成这项工作。

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

    将父名称非规范化为 Child 上的字段,如下所示:

    类子(ndb.Model): 父 = ndb.KeyProperty(种类=父,索引=真) 名称 = ndb.StringProperty() parent_name = ndb.StringProperty()

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

    如果这是用于类似 http 处理程序的东西,并且您需要返回包含 10 个结果或其他内容的页面,您可以首先获取按名称排序的 10 个父母,然后对拥有其中一位父母的所有孩子运行查询 @987654323 @(这是您在评论中建议的)。您将不得不在事后按父母姓名订购孩子。这种方法的问题是,它一次只适用于有限数量的父母(我忘记了你可以传递多少个值给.IN())。此外,当您在 order_parent_keys 的原始组中没有孩子并且需要获取下一组时,分页会变得很奇怪。

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

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

【讨论】:

以上是关于在 NDB 中按父字段查询子表和排序结果的主要内容,如果未能解决你的问题,请参考以下文章

主表和子表是一对多,查询主表数据以及子表的某一条数据

mysql中按时间段查询

在 Objection.js 中按急切结果计数排序记录并实现分页?

在 Wordpress 中按两个元 ACF 字段排序

SQL关联两张表查数据,结果只显示一条。

MySql 查询出对应子表的某个字段,并且关联起来