是否有任何聪明的方法可以避免在下列情况下使用IN子句进行代价高昂的查询?
我正在使用Google App Engine构建Facebook应用程序,在某些时候我(显然)需要查询数据存储区以获取属于给定用户的任何facebook朋友的所有实体。
假设我有几个实体建模:
class Thing(db.Model):
owner = db.ReferenceProperty(reference_class=User, required=True)
owner_id = db.StringProperty(required=True)
...
和
class User(db.Model):
id = db.StringProperty(required=True)
...
在某些时候,我查询Facebook以获取给定用户的朋友列表,我需要执行以下查询
# get all Thing instances that belong to friends
query = Thing.all()
query.filter('owner_id IN', friend_ids)
如果我这样做,AppEngine会为friend_ids
中的每个id执行子查询,可能超过任何查询可以生成的子查询的最大数量(30)。
有没有更好的方法(即最小化查询次数)?
我了解使用数据存储区没有任何关系和联接,但特别是,我会考虑向User
或Thing
类添加新字段,如果它有助于简化操作。
答案 0 :(得分:5)
我认为没有一个优雅的解决方案,但你可以试试这个:
在用户模型上,使用Facebook ID作为键名,并将每个用户的事物列表存储在ListProperty中。
class Thing(db.Model):
...
class User(db.Model):
things = db.ListProperty(db.Key)
...
实体创建将如下所示:
user = User.get_or_insert(my_facebook_id)
thing = Thing()
thing.put()
user.things.append(thing.key())
user.put()
检索需要2个查询:
friends = User.get_by_key_name(friend_ids)
thing_keys = []
for friend in friends:
thing_keys.extend(friend.things)
things = db.get(thing_keys)
答案 1 :(得分:3)
This Google I/O talk解决了你正在处理的确切情况。另见今年his follow up talk。