App Engine Datastore IN 运算符 - 如何使用?

3 投票
2 回答
2788 浏览
提问于 2025-04-15 12:17

阅读链接: http://code.google.com/appengine/docs/python/datastore/gqlreference.html

我想使用:

:= IN

但是我不太确定怎么让它工作。假设有以下内容:

class User(db.Model):
    name = db.StringProperty()

class UniqueListOfSavedItems(db.Model):
    str = db.StringPropery()
    datesaved = db.DateTimeProperty()

class UserListOfSavedItems(db.Model):
    name = db.ReferenceProperty(User, collection='user')
    str = db.ReferenceProperty(UniqueListOfSavedItems, collection='itemlist')

我该如何查询以获取某个用户保存的项目列表?显然,我可以这样做:

q = db.Gql("SELECT * FROM UserListOfSavedItems WHERE name :=", user[0].name)

但这样得到的只是一个键的列表。我现在想把这个列表用在一个查询中,以从 UniqueListOfSavedItems 中获取 str 字段。我原以为可以这样做:

q2 = db.Gql("SELECT * FROM UniqueListOfSavedItems WHERE := str in q")

但似乎有什么地方不对……有没有什么想法?是因为(我在上班,所以现在不能测试):

q2 = db.Gql("SELECT * FROM UniqueListOfSavedItems __key__ := str in q)

顺便说一下,这个问题真是难以搜索,因为我真正关心的就是 "IN" 操作符。

2 个回答

0

给Adam点个赞,他让我找到了正确的方向。根据他的提示,我在代码搜索中查找了一些资料,得到了以下解决方案。

usersaveditems = User.Gql(“Select * from UserListOfSavedItems where user =:1”, userkey)

saveditemkeys = []

for item in usersaveditems:
    #this should create a list of keys (references) to the saved item table
    saveditemkeys.append(item.str())    

if len(usersavedsearches > 0):
    #and this should get me the items that a user saved
    useritems = db.Gql(“SELECT * FROM UniqueListOfSavedItems WHERE __key__ in :1’, saveditemkeys)
10

既然你已经有了一组键,那就不需要再进行第二次查询了——可以直接批量获取数据。试试这个:

#and this should get me the items that a user saved
useritems = db.get(saveditemkeys)

(注意,你甚至不需要加保护条件——对0个实体进行db.get操作会自动处理好。)

你可能会问,这有什么区别呢?其实,db.get操作大约需要20到40毫秒。而查询(无论是GQL还是其他)大约需要160到200毫秒。但等等,情况还会更糟!IN操作是在Python中实现的,它会转换成多个查询,这些查询是一个接一个执行的。所以如果你用IN过滤器查询10个键,那就相当于要执行10个各自大约160毫秒的查询,总共大约需要1.6秒的时间。而一个单独的db.get操作,效果是一样的,但只需要大约30毫秒。

撰写回答