Минимизируйте подзапросы с запросами IN на AppEngine (python) - PullRequest
6 голосов
/ 19 октября 2010

Есть ли какой-нибудь умный способ избежать выполнения дорогостоящего запроса с предложением 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, вероятно, превысив максимальное количество подзапросов, которое может вызвать любой запрос (30).

Есть ли лучший способ сделать это (то есть свести к минимуму количество запросов)? Я понимаю, что нет отношений и объединений, использующих хранилище данных, но, в частности, я хотел бы рассмотреть возможность добавления новых полей в класс User или Thing, если это поможет упростить задачу.

Ответы [ 2 ]

5 голосов
/ 19 октября 2010

Не думаю, что есть элегантное решение, но вы можете попробовать это:

В модели User используйте 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)
3 голосов
/ 19 октября 2010

В этом выступлении Бретта Слаткина, посвященном вводу / выводу Google , рассматривается конкретная ситуация, с которой вы имеете дело.См. Также его последующий доклад в этом году.

...