假设我有相同类型的实体 a、b 和 c,情况是这样的:
实体 a 是实体 b 的父级 实体 b 是实体 c 的父级
现在,如果我执行以下查询
query = ndb.Query(ancestor=a.key)
result = query.fetch()
结果将包含 b 和 c 实体。有没有办法可以过滤掉 c 以便只保留直接后代的实体?除了我检查结果并删除它们之外的任何方式,我的意思是。
假设我有相同类型的实体 a、b 和 c,情况是这样的:
实体 a 是实体 b 的父级 实体 b 是实体 c 的父级
现在,如果我执行以下查询
query = ndb.Query(ancestor=a.key)
result = query.fetch()
结果将包含 b 和 c 实体。有没有办法可以过滤掉 c 以便只保留直接后代的实体?除了我检查结果并删除它们之外的任何方式,我的意思是。
这样做的唯一方法是修改您的架构,添加一个KeyProperty
引用实体的直接父级的“父级”,然后对其进行过滤。
实际上,这根本不受支持。尼克的回答确实有效,但前提是您可以在查询中指定 OP 未指定的实体类型:
“Kindless 查询不能包含属性过滤器。但是,它们可以通过传递 Entity.KEY_RESERVED_PROPERTY 作为过滤器的属性名称来按实体键进行过滤。还支持对 Entity.KEY_RESERVED_PROPERTY 进行升序排序。”
这有点晚了,但它会帮助任何有同样问题的人。
解决方案是首先进行仅键查询并获取直接后代的键子集。
使用该键子集,您可以批量获取所需的实体。
我对python不熟悉,所以这里有一个例子:
directDescKeys := make([]*datastore.Key, 0)
q := datastore.NewQuery("A").Ancestor(parentKey).KeysOnly()
for it := q.Run(ctx);; {
key, err := it.Next(nil)
if err == datastore.Done {
break
} else if err != nil {
// handle error
}
if reflect.DeepEquals(key.Parent(), parentKey) {
directDescKeys = append(directDescKeys, key)
}
}
entities := make([]*A, len(directDescKeys))
if err := datastore.GetMulti(ctx, directDescKeys, entities); err != nil {
// handle error
}