为什么在未提供祖先时查询没有 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" 几秒(不太可能)。
请参阅此相关答案:,其中还解释了祖先键和查询。
为什么未指定祖先时过滤器不起作用?不管祖先是什么,它不应该在实体类型上工作吗?
我的用例:我已经设置了几个具有父键的实体。该键对应于另一个实体(主实体),以便我可以通过祖先(主实体键)获取子项。
但是问题似乎是我无法再查询实体属性,除非我指定祖先。这是它应该工作的方式吗?下面是一些伪代码。如果问题不清楚,我可以提供工作代码。
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" 几秒(不太可能)。
请参阅此相关答案: