数据存储上的层次查询

2 投票
1 回答
554 浏览
提问于 2025-05-01 06:50

我正在尝试在App Engine上创建层级查询。

我的数据存储中有父母和孩子。每个父母都有孩子。想象一下,我需要找到孩子。我对父母和孩子都有条件,比如说,假设这是一个真实的家庭数据存储,我的条件是:我想要所有35岁或以上的父亲所生的男孩。

我现在的查询大概是这样的:

P = Parent.query(Parent.age >= 35)
for p in P:
    C = Children.query(gender == "boy", ancestor = p.key)
    for c in C:
        -> here I print information on the children 

但是这个查询在有很多父母和孩子的情况下非常慢。我想避免使用像for循环这样的迭代,因为我觉得这样会花很多时间!有什么好的方法可以快速执行这种查询吗?

我还有兄弟姐妹的信息,如果我想找所有父母超过35岁并且有一个叫“Sisi”的姐妹的孩子,我会这样查询(每个孩子都有一个“brother”值来表示他的兄弟):

 P = Parent.query(Parent.age >= 35)
        for p in P:
            C = Children.query(gender == "girl", name == "Sisi", ancestor = p.key)
            for c in C:
                C1 = Children.query(gender == "boy", brother == c.key, ancestor = p.key)
                for c1 in C1:
                    ->Here I print information about the children

实际上,这个家庭的例子对我的项目很有帮助,但它也说明了我面临的问题。

暂无标签

1 个回答

1

我之前能做到这一点的方法是把关键字存储在一个单独的查找实体中。这是基于键值存储的理念,有时候为了更快地查找,重复的信息是必要的。举个例子:

ParentChildLookup
 - parent_key = ndb.KeyProperty()
 - child_key = ndb.KeyProperty()

如果你要处理孙子孙女的信息,还可以增加一个第三个维度:

ParentChildLookup
 - parent_key = ndb.KeyProperty()
 - child_key = ndb.KeyProperty()
 - grandchildren_key = ndb.KeyProperty()

如果你想一次性查找所有信息,可以添加重复的条件,把孩子和孙子孙女都放在一个列表里:

ParentChildLookup
 - parent_key = ndb.KeyProperty()
 - child_key = ndb.KeyProperty(repeated=True)
 - grandchildren_key = ndb.KeyProperty(repeated=True)

每当关系发生变化时,你都需要插入或更新这些查找值。这样做的好处是可以避免很多查询,特别是嵌套查询或多属性查询。如果你不喜欢这种方法,我建议你看看这里的“关系模型”解释:https://cloud.google.com/appengine/articles/modeling。你可以在不需要把所有对象都存储在同一个实体中的情况下,存储多对多对象之间的关系。

撰写回答