Минимизировать вложенные запросы с помощью in-запросов на AppEngine (python)
есть ли какой-либо умный способ избежать дорогостоящего запроса с предложением 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 выполнил бы подзапрос для каждого id в friend_ids
, вероятно, превышающее максимальное количество подзапросов, которые может породить любой запрос (30).
есть ли лучший способ сделать это (т. е. минимизация числа запросов)?
Я понимаю, что нет никаких отношений и соединений с использованием хранилища данных, но, в частности, я бы рассмотрел возможность добавления новых полей в the User
или Thing
класс, если это помогает сделать вещи проще.
2 ответов
Я не думаю, что есть элегантное решение, но вы могли бы попробовать это:
в модели пользователя используйте 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)
это Google I/O talk Бретт Слаткин обращается к точной ситуации, с которой Вы имеете дело. См. также его последующие разговоры в этом году.