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

huangapple go评论86阅读模式
英文:

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)
}

// 这个可以工作
_, err := datastore.NewQuery("table1").Ancestor(kparent).Filter("Unique =", v.Unique).GetAll(cx, dst)

// 没有祖先的过滤查询不起作用。返回无结果错误。
_, err := datastore.NewQuery("table1").Filter("Unique =", v.Unique).GetAll(cx, dst)

请注意,我只翻译了你提供的代码部分。如果你还有其他问题或需要进一步的帮助,请告诉我。

英文:

Why the filter doesn't work when the ancestor is not specified? Isn't it supposed to work on entity type regardless the ancestor?

My use case: I've set-up several entities with a parent key. The key corresponds with another entity (the main entity) so that I can get the children by ancestor(main entity key).

However the issue seems to be that I can't query the entity properties anymore unless I specify the ancestor. Is this the way it should work? Below is some pseudo code. I can provide working code if the issue is not clear.

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)

答案1

得分: 1

简短回答:

具有父实体的实体可以使用非祖先查询进行查询(即不使用Query.Ancestor()方法指定祖先)。显然,被过滤的属性必须建立索引。

解释:

在你的例子中,与你的命名相反,key1是父键,kparent是你保存实体的键。

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

在你的例子中,你找到了结果,因为实体的键恰好是你指定的键。通常,祖先查询是这样使用的:指定父键(而不是实体的键本身),在你的例子中是key1

**需要注意的是:祖先查询是强一致性的。**这意味着如果你保存了一个带有父实体的实体,并在此之后执行一个祖先查询(其中祖先过滤器是相同的父实体),你将立即在查询结果中看到保存的实体。

非祖先查询只是最终一致性的。这意味着如果你保存了一个实体,并在此之后执行一个非祖先查询,查询结果中不包括新保存的实体的可能性非常高,这很可能是你的情况。

按属性建立的索引仅依赖于属性的值,并且与实体的键无关,因此键是否具有父键并不重要。一旦为新实体创建了属性的索引条目,通过该属性进行过滤的查询将包括该实体。这可能只需要几毫秒或几秒钟(不太可能)。

请参阅这个相关的答案:如何过滤GAE查询?,其中还解释了祖先键和查询。

英文:

Short answer:

Entities saved with a parent can be queried with non-ancestor queries (where you don't specify an ancestor with the Query.Ancestor() method). Obviously the filtered property must be indexed.

To put things in place:

In your example contrary to your naming key1 is the parent key and kparent is the key you save the entity with.

When you create an Ancestor query with the Query.Ancestor() method, the ancestor filter limits the results to the specified entity and its descendants: so you specify a parent key, and the results will be the entities with this key (0 or 1 entity) and those where this is the parent key!

In your example you find the result because the entity's key is exactly the one you specified. Usually ancestor queries are used in a way that the parent key is specified (not the entity's key itself) which in your example is key1.

Important to note: Ancestor queries are strongly consistent. This means that if you save an entity with a parent and you perform an ancestor query right after that (where the ancestor filter is the same parent of course), you will see the saved entity immediately in the query results.

Non-ancestor queries are only eventually consistent. This means that if you save an entity and you perform a non-ancestor query right after that, chances that the query will not include the newly saved entity is very high, which is most likely your case.

An index by a property only depends on the property's value and is independent from the key of the entity, so it doesn't matter if the key has a parent or not. Once the index entry for the property is created for a new entity, queries filtering by that property will include the entity. This may take as short as a few millisec or as "long" as a few sec (unlikely).

Please see this relevant answer: How to filter a GAE query? which also explains ancestor keys and queries.

答案2

得分: 0

你正在比较两个不同的查询 - 祖先键不是唯一的区别。例如,如果过滤属性没有建立索引,第二个查询将不返回任何结果。

英文:

You are comparing two different queries - and the ancestor key is not the only difference. The second query will return no results if the filter property is not indexed, for example.

huangapple
  • 本文由 发表于 2015年4月9日 11:35:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/29529296.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定