使用AppEngine(python)上的IN查询最小化子查询

aba*_*gat 6 python google-app-engine gql gquery google-cloud-datastore

是否有任何聪明的方法可以避免在以下情况下使用IN子句进行代价高昂的查询?

我正在使用Google App Engine构建Facebook应用程序,并且在某些时候我(显然)需要查询数据存储区以获取属于给定用户的任何facebook朋友的所有实体.

假设我有几个实体建模:

class Thing(db.Model):
    owner = db.ReferenceProperty(reference_class=User, required=True)
    owner_id = db.StringProperty(required=True)
    ...
Run Code Online (Sandbox Code Playgroud)

class User(db.Model):
    id = db.StringProperty(required=True)
    ...
Run Code Online (Sandbox Code Playgroud)

在某些时候,我查询Facebook以获取给定用户的朋友列表,我需要执行以下查询

# get all Thing instances that belong to friends
query = Thing.all()
query.filter('owner_id IN', friend_ids)
Run Code Online (Sandbox Code Playgroud)

如果我这样做,AppEngine将为每个id执行子查询friend_ids,可能超过任何查询可以生成的子查询的最大数量(30).

有没有更好的方法来做到这一点(即最小化查询数量)?我知道使用数据存储区没有任何关系和连接,但是,特别是,如果它有助于使事情变得更容易,我会考虑向UserThing类添加新字段.

Dre*_*ars 5

我不认为有一个优雅的解决方案,但你可以试试这个:

在用户模型上,使用Facebook ID作为键名,并将每个用户的事物列表存储在ListProperty中.

class Thing(db.Model):
  ...

class User(db.Model):
  things = db.ListProperty(db.Key)
  ...
Run Code Online (Sandbox Code Playgroud)

实体创建将如下所示:

user = User.get_or_insert(my_facebook_id)

thing = Thing()
thing.put()

user.things.append(thing.key())
user.put()
Run Code Online (Sandbox Code Playgroud)

检索需要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)
Run Code Online (Sandbox Code Playgroud)