Google Cloud Datastore:如何查询所有不同的 Parent/Ancestor?
Google Cloud Datastore: how to query all distinct Parent/Ancestor?
我有一个名为 Order
的数据存储类型,它有一个 ancestor/parent User
.
我想使用 GQL 查询订单的所有不同祖先(用户),但以下查询不起作用。
SELECT DISTINCT User FROM Order
查询的响应是:
No entities matched this query.
Make sure there are either simple or composite indexes for the properties you are searching. Learn more
由于parent也是key的一部分,我也试过:
SELECT DISTINCT __key__ FROM Order
但是错误响应说:
GQL query error: Group by is not supported for the property: key
您应该注意,数据存储祖先并不是在实体 kind 级别建立的:您不能真正说 Order
kind 有一个 User
种类 作为祖先。
祖先是在 实体 级别建立的 - 只有在实体创建级别指定了祖先时,实体才有祖先,否则它没有祖先。同样,祖先实体的种类无关紧要,同一种类的不同实体可以有不同种类的祖先或根本没有祖先。
考虑到这一点,听起来您的每个 Order
实体都有一个 User
实体作为祖先。
血统关系的存在将所有相关实体置于同一个实体组中。所有没有祖先的实体都被放入它们自己的实体组中(它们是实体组 roots/leaders)。
在你的例子中,Order
个实体被放置在它们各自的 User
个实体的实体组中。
进行祖先查询时(即指定特定祖先或后代实体),查询结果将仅限于该特定实体组的范围。这允许以事务方式进行此类查询,并获得高度一致的结果。
有关祖先查询语法的示例,请参阅 HAS ANCESTOR and HAS DESCENDANT clauses in google cloud datastore。
缺点是您不能跨多个实体组进行祖先查询。在您的情况下,您正在查询 User
个实体,它们位于不同的实体组中。即使你将所有 User
实体放在同一个组中(通过为它们指定一个共同的祖先键)你仍然无法得到你想要的东西,因为你正在寻找不同的祖先 Order
,这是一个 "descendant condition" - 一个 Order
只能有一个 User
作为祖先。
这让我们找到了问题的根本原因:您正在使用实体祖先来模拟实体关系。这不是祖先的设计目的,它是为强一致性而设计的。我知道,这听起来很混乱。
您可以做的是忘记数据存储的祖先,使用普通键属性为您的关系建模,没有任何限制。另见
我会在 User
类型中添加一个 order_count
属性,在 Order
类型中添加一个 user
键 属性。每当创建订单时,我都会创建一个 Order
实体,并将其 user
属性 设置为相应的 User
实体键,然后我会增加 order_count
该 User
实体的 属性。然后,为了得到你想要的,你只需要查询 User
具有非零 order_count
.
的实体
我有一个名为 Order
的数据存储类型,它有一个 ancestor/parent User
.
我想使用 GQL 查询订单的所有不同祖先(用户),但以下查询不起作用。
SELECT DISTINCT User FROM Order
查询的响应是:
No entities matched this query.
Make sure there are either simple or composite indexes for the properties you are searching. Learn more
由于parent也是key的一部分,我也试过:
SELECT DISTINCT __key__ FROM Order
但是错误响应说:
GQL query error: Group by is not supported for the property: key
您应该注意,数据存储祖先并不是在实体 kind 级别建立的:您不能真正说 Order
kind 有一个 User
种类 作为祖先。
祖先是在 实体 级别建立的 - 只有在实体创建级别指定了祖先时,实体才有祖先,否则它没有祖先。同样,祖先实体的种类无关紧要,同一种类的不同实体可以有不同种类的祖先或根本没有祖先。
考虑到这一点,听起来您的每个 Order
实体都有一个 User
实体作为祖先。
血统关系的存在将所有相关实体置于同一个实体组中。所有没有祖先的实体都被放入它们自己的实体组中(它们是实体组 roots/leaders)。
在你的例子中,Order
个实体被放置在它们各自的 User
个实体的实体组中。
进行祖先查询时(即指定特定祖先或后代实体),查询结果将仅限于该特定实体组的范围。这允许以事务方式进行此类查询,并获得高度一致的结果。
有关祖先查询语法的示例,请参阅 HAS ANCESTOR and HAS DESCENDANT clauses in google cloud datastore。
缺点是您不能跨多个实体组进行祖先查询。在您的情况下,您正在查询 User
个实体,它们位于不同的实体组中。即使你将所有 User
实体放在同一个组中(通过为它们指定一个共同的祖先键)你仍然无法得到你想要的东西,因为你正在寻找不同的祖先 Order
,这是一个 "descendant condition" - 一个 Order
只能有一个 User
作为祖先。
这让我们找到了问题的根本原因:您正在使用实体祖先来模拟实体关系。这不是祖先的设计目的,它是为强一致性而设计的。我知道,这听起来很混乱。
您可以做的是忘记数据存储的祖先,使用普通键属性为您的关系建模,没有任何限制。另见
我会在 User
类型中添加一个 order_count
属性,在 Order
类型中添加一个 user
键 属性。每当创建订单时,我都会创建一个 Order
实体,并将其 user
属性 设置为相应的 User
实体键,然后我会增加 order_count
该 User
实体的 属性。然后,为了得到你想要的,你只需要查询 User
具有非零 order_count
.