如何使用实体密钥在GQL中进行查询


72

如何在Google App Engine数据查看器中使用GQL针对实体关键字编写查询?

在查看器中,第一列(Id / Name)显示为name=_1,在详细信息视图中,该键将显示为

Decoded entity key: Programme: name=_1
Entity key: agtzcG9................... 

此查询不起作用:

SELECT * FROM Programme where name = '_1'

Answers:


106

您可以使用实体的密钥来检索它:

SELECT * FROM Programme where __key__ = KEY('agtzcG9...................')

并且,您应该能够使用类似的名称进行查询:

SELECT * FROM Programme where __key__ = KEY(Programme, '_1')

请注意,这不是您要在AppEngine应用程序中执行的操作;正如尼克在评论中指出的那样,这是浪费时间。确实,此示例仅是向您展示如何在管理控制台中通过Key进行查询。


4
啊,不。这是浪费大量的时间和资源。
尼克·约翰逊

4
@Nick:但是在管理控制台中,可能没有更好的方法。
Thilo 2010年

4
是否可以通过ID而不是键进行查询?
tensaix2j

当您只需要知道某物是否存在时,按键查询的计数操作是找出实体是否存在的绝对最快的方法。如果需要进行键获取,则可以对键查询进行计数,如果> 0,则您已经知道该键。如果您需要实体本身,请按照尼克的建议进行操作,然后对实体执行get()。
Ajax

记住,您只需要引用id是一个字符串即可。如果是数字,则不要引用它。因此,如果id是一个数字,值为888,则上面的查询将是SELECT * FROM Program,其中key = KEY('Programme',888)
Ezward

20

对于数字ID,类似于按名称查询的形式适用:

SELECT * from Programme where __key__ = KEY('Programme', 1234567)

我发现此表单在管理控制台中特别有用。


18

您根本不需要查询即可通过键获取实体-您只需通过其键即可获取实体。在Python中,您可以使用MyModel.get_by_key_name('_1')。这比Adam建议使用查询快3至5倍。


5
尼克,这不是我的建议,我只是想帮助他让他的查询工作。我认为他正在尝试在管理控制台数据查看器中查看内容。
亚当·克罗斯兰

@ Nick + Adam:是的,我正在尝试在管理控制台中查看一些数据。
Thilo 2010年

1
对于记录,__key__查询实际上通常直接从实体表本身读取,而不是先从索引然后是实体表读取。因此在实践中,当数据存储区将此查询编译为原始的bigtable查找或扫描时,__key__ ==查询和不会有太大区别get()。当然,这是一个实现细节。get()当您查找单个实体时,仍然是一种好习惯。
ryan

瑞安,__key__查询永远不会从实体表中读取。他们从索引表中读取,索引表包括除实体表以外的所有表。索引表都指向一个键,因此无论您使用什么索引进行搜索,这都是键的来源。在1.6.5中,有一些投影查询可以以与键查询相同的价格实际读取键和匹配的索引数据……也就是说,您不必在实体表上进行争用。
阿贾克斯(Ajax)2012年

1
@Ajax交叉线。ryan谈论的查询形式为“ SELECT * FROM Kind WHERE key =:1”;您正在谈论的是“ SELECT key FROM Kind ...”形式的查询。您对各自的查询类型都是正确的。
尼克·约翰逊

2

通过键查询时,您需要完全匹配键,包括父键,而不仅仅是ID或名称。当然,如果父级为null(如上例所示),则ID或Name以及实体类型就足够了。

如果您已经编码了实体密钥,则可以像这样使用:

SELECT * FROM Programme where __key__ = KEY('agtzcG9...................')

对于上面的简单示例,

SELECT * FROM Programme where __key__ = KEY('Programme', '_1')

可以,但是如果您的钥匙有父母,例如

Paren: id=123

然后查询将是

SELECT * FROM Programme where __key__ = KEY('Paren', 123, 'Programme', '_1')

如果父母本身有父母,则也需要添加它。有关更多详细信息,请参见官方GQL文档

似乎没有一种方法可以选择具有相同ID或名称的所有对象,而与父对象无关。


1

对此,请注意以下几点:当我在KEY中的任何参数周围使用任何引号时,调用将失败(在管理控制台中,我会看到错误弹出窗口)。

例如,键入“MYTYPE”与ID /名称12345,这确实工作:

SELECT * FROM mytype WHERE __key__ = KEY('mytype', '12345')

但这确实是:

SELECT * FROM mytype WHERE __key__ = KEY(mytype, 12345)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.