为什么查询在没有提供祖先时不返回结果? [英] Why the query doesn't return results when the ancestor is not provided?

查看:103
本文介绍了为什么查询在没有提供祖先时不返回结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我的用例:我用父键设置了几个实体。密钥与另一个实体(主实体)相对应,以便我可以通过祖先(主实体密钥)获取子代。



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

  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)。Ascentor kparent).Filter(Unique =,v.Unique).GetAll(cx,dst)

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

解决方案

简短回答:使用父级保存的实体可以查询非祖先查询(您未指定具有 Query.Ancestor() 方法)。显然,过滤过的属性必须被编入索引。



为了实现目标:

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

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



在您的示例中,您可以找到结果,因为该实体的密钥就是您指定的密钥。通常祖先查询的使用方式是指定父键(而不是实体的键本身),在你的例子中它是 key1



注意:祖先查询是非常一致的。这意味着如果您保存一个实体与一个父代,并且在此之后执行一个祖代查询(其中祖代过滤是同样的父母当然),你立即在查询结果中看到保存的实体。



非祖先查询最终只是一致的即可。这意味着如果你保存一个实体并在那之后执行一个非祖先查询,那么这个查询将不包含新保存的实体的机会非常高,这很可能是你的情况。



属性的索引只取决于属性的值,并且与实体的键无关,因此键是否具有父键也没关系。一旦为新实体创建了该属性的索引条目,那么由该属性过滤的查询将包含该实体。这可能需要短至几毫秒或几(几乎不可能)。



请参阅相关答案:如何过滤GAE查询?,这也解释了祖先的密钥和查询。


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)

解决方案

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.

这篇关于为什么查询在没有提供祖先时不返回结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆