如何在NDB中查询Child表并按Parent的字段对结果排序
实现方案
Google Cloud Datastore(NDB底层依赖的存储服务)本身不支持跨实体的Join查询,无法直接在Child的查询语句中关联Parent的name字段做排序,要实现数据库层面的排序无需Python内存处理,最优方案是做字段冗余,具体实现如下:
方案1:冗余存储Parent名称到Child实体(推荐)
该方案可以直接通过NDB原生查询实现排序,完全走索引,性能最优,适合Parent名称更新频率不高的场景。
- 调整模型定义,新增冗余字段并加自动同步逻辑
from google.appengine.ext import ndb class Parent(ndb.Model): name = ndb.StringProperty() def _pre_put_hook(self): # Parent名称更新时,同步更新所有关联Child的冗余字段 if self.key.id: related_children = Child.query(Child.parent == self.key).fetch() for child in related_children: child.parent_name = self.name ndb.put_multi(related_children) class Child(ndb.Model): parent = ndb.KeyProperty(kind=Parent, indexed=True) name = ndb.StringProperty() # 新增冗余字段,存储关联Parent的name,加索引支持排序 parent_name = ndb.StringProperty(indexed=True) def _pre_put_hook(self): # 新增/更新Child时自动同步Parent名称 if self.parent: parent_obj = self.parent.get() if parent_obj: self.parent_name = parent_obj.name
- 后续查询直接按冗余字段排序即可
# 按Parent name升序查询 sorted_child_asc = Child.query().order(Child.parent_name).fetch() # 按Parent name降序查询 sorted_child_desc = Child.query().order(-Child.parent_name).fetch()
补充说明
如果你的业务场景中Parent的name字段更新频率极高,冗余字段的写入开销会比较大,这种情况下只能先查询符合条件的Child,再批量获取关联的Parent实体,在Python内存中做排序,该方案仅适合数据量较小的场景,不符合你不想在代码层面做排序的需求,因此不推荐。
内容的提问来源于stack exchange,提问作者Erfan
相关产品推荐
相关产品推荐

