谷歌应用引擎GQL查询两个具有相同字符串的属性

3

我有一个名为Game的数据模型。

Game模型中,我有两个属性称为player1player2,它们是玩家的名称。

我想在game中找到一个玩家,但我不知道如何构建查询,因为gql不支持OR语句,所以我不能使用select * from Game where player1 = 'tom' or player2 = 'tom'语句。

那么,我该如何解决这个问题?
我需要修改我的数据模型吗?

3个回答

6

在您当前的数据模型下,您需要进行两次查询,一次针对玩家1,一次针对玩家2,然后在本地Python代码中将结果合并。

另一个选项是需要更改模式,用单个ListProperty替换这两个字段,例如:

class Game(db.Model):
  players = db.ListProperty()

game1.players = ['tom', 'bob']
game2.players = ['joe', 'tom']

# this query will match all games where tom is one of the players
query = Game.all().filter('players =', 'tom')

这是因为现在可以使用单个索引查询玩家。

1
我同意Drew的答案是正确的,但如果你被你的模式所限制或者只是想探索其他选项,你可以考虑使用Python的sets来查找这两个查询的并集。
name = "The Player"
keys1 = set(Game.all(keys_only=True).filter("player1 =", name))
keys2 = set(Game.all(keys_only=True).filter("player2 =", name))
games = Game.get( list(keys1 | keys2) )

这个例子将使用3个RPC调用/查询,但是通过仅获取键来执行联合操作,您可以比通常更快地进行查询。然而,根据您过滤的记录数量,您可能会发现没有键的查询更快,并使用类似于简单检查的方法。

games1 = Game.all().filter("player1 =", name)
games2 = Game.all().filter("player2 =", name)
games = games1+filter(lambda x:x not in games1,games2)

0
请注意,使用Drew的模式不会提高性能,因为列表属性中的查询必须针对列表的所有元素进行相等性检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接