Why the query doesn't return results when the

2019-07-23 13:44发布

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)

2条回答
The star\"
2楼-- · 2019-07-23 14:21

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.

查看更多
别忘想泡老子
3楼-- · 2019-07-23 14:42

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.

查看更多
登录 后发表回答