为什么在未提供祖先时查询没有 return 结果?

Why the query doesn't return results when the ancestor is not provided?

为什么未指定祖先时过滤器不起作用?不管祖先是什么,它不应该在实体类型上工作吗?

我的用例:我已经设置了几个具有父键的实体。该键对应于另一个实体(主实体),以便我可以通过祖先(主实体键)获取子项。

但是问题似乎是我无法再查询实体属性,除非我指定祖先。这是它应该工作的方式吗?下面是一些伪代码。如果问题不清楚,我可以提供工作代码。

type MyStruct{
  Unique int
}

 key1 := datastore.NewKey(c, "table1", "verylongstring", 0, nil)
 kparent :=  datastore.NewKey(c, "table1", "anotherlongstring", 0, key1)
 x := MyStruct{Unique:23}
 if _, err := datastore.Put(c, kparent, &x); err != nil {
        panic(err)
 }

// This works
 _, err := datastore.NewQuery("table1").Ascentor(kparent).Filter("Unique =", v.Unique).GetAll(cx, dst)

// Query with filter without ancestor doesn't work. Returns no results error.
 _, err := datastore.NewQuery("table1").Filter("Unique =", v.Unique).GetAll(cx, dst)

您正在比较两个不同的查询 - 祖先键不是唯一的区别。例如,如果过滤器 属性 未编入索引,第二个查询将 return 没有结果。

简答:

与父 一起保存的实体可以 使用非祖先查询进行查询(您不使用 Query.Ancestor() 方法指定祖先)。显然过滤后的属性一定要索引

整理东西:

在您的示例中,与您的命名相反,key1 是父键,kparent 是您用来保存实体的键。

当您使用 Query.Ancestor() 方法创建祖先查询时,ancestor filter 将结果限制为指定的实体及其后代:因此您指定了一个父键,结果将是具有此键的实体(0 或 1 个实体)以及这是父键的实体!

在您的示例中,您找到了结果,因为实体的键正是您指定的键。通常祖先查询的使用方式是指定父键(而不是实体的键本身),在您的示例中是 key1.

需要注意的重要事项:祖先查询是高度一致的。这意味着如果您保存具有父实体的实体并在之后立即执行祖先查询(其中祖先过滤器当然是同一个父项),您立即在查询结果中看到保存的实体。

非祖先查询仅最终一致。这意味着如果您保存一个实体并在之后立即执行非祖先查询,则该查询不包含新保存的实体的可能性非常高,这很可能是您的情况。

属性 的索引只依赖于 属性 的值,独立于实体的键,所以键是否有父项并不重要.为新实体创建 属性 的索引条目后,按 属性 筛选的查询将包括该实体。这可能需要几毫秒或 "long" 几秒(不太可能)。

请参阅此相关答案:,其中还解释了祖先键和查询。