我有一个名为Game
的数据模型。
在Game
模型中,我有两个名为player1
和player2
的属性。
我想在game
中找到一个播放器,但我不知道如何构建查询,因为gql不支持OR
子句然后我不能使用select * from Game where player1 = 'tom' or player2 = 'tom'
语句
那么,我该如何解决这个问题呢? 我是否必须修改我的数据模型?
答案 0 :(得分:6)
使用您当前的数据模型,您需要进行2次查询,一次针对player1,另一次针对player2,然后将结果合并到本地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 :(得分: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)
答案 2 :(得分:0)
请注意,使用Drew的架构没有性能提升,因为列表属性中的查询必须检查列表中所有元素的相等性。