Эффективный способ сделать большой запрос IN в Google App Engine?

Пользователь обращается к своим контактам на своем мобильном устройстве. Я хочу отправить на сервер все номера телефонов (скажем 250), а затем запросить для любых пользовательских объектов, имеющих соответствующие номера телефонов.

У пользователя есть поле телефона, которое индексируется. Поэтому я занимаюсь User.query(User.phone.IN(phone_list)) , но я просто посмотрел на AppStats, и это чертовски дорого. Это стоило мне 250 прочтений для этой одной операции, и это то, что я ожидаю от пользователя делать часто.

Какие альтернативы? Я полагаю, что я могу установить значение идентификатора объекта пользователя как его номер телефона (т. user = User(id = phone_number) При создании пользователя я бы сделал user = User(id = phone_number) ), а затем напрямую получал ключи через ndb.get_multi(phones) , но Я также хочу выполнить этот же запрос с помощью электронной почты.

Есть идеи?

Вы можете создать модель PhoneUser следующим образом:

 from google.appengine.ext import ndb class PhoneUser(ndb.Model): number = ndb.StringProperty() user = ndb.KeyProperty() class User(ndb.Model): pass u = User() u.put() p = PhoneUser(id='123-456-7890', number='123-456-7890', user=u.key) p.put() u2 = User() u2.put() p2 = PhoneUser(id='555-555-5555', number='555-555-5555', user=u2.key) result = ndb.get_multi([ndb.Key(PhoneUser, '123-456-7890'), ndb.Key(PhoneUser, '555-555-5555')]) 

Я думаю, что это будет работать в этой ситуации. Вам просто нужно будет добавлять / удалять вашу модель PhoneUser всякий раз, когда вы обновляете пользователя. Вы можете сделать это, используя post hooks: https://developers.google.com/appengine/docs/python/ndb/modelclass#Model__post_delete_hook

Я неправильно понял часть вашей проблемы, я думал, что вы отправляете запрос, который дает вам 250 объектов.

Теперь я вижу, в чем проблема: вы отправляете запрос IN со списком из 250 телефонных номеров, за кулисами, хранилище данных на самом деле делает 250 отдельных запросов, поэтому вы получаете 250 операций чтения.

Я не могу придумать, как избежать этого. Я бы рекомендовал избегать поиска по длинным спискам телефонных номеров. Это похоже на то, что вам нужно сделать только один раз, когда пользователь впервые будет использовать этот телефон. Попробуйте найти способ хранения результатов и снова избежать запроса.

нет эффективного способа сделать запрос IN. поэтому вместо этого избегайте всего этого.

как?

инвертируйте запрос, вместо того чтобы найти всех людей, принадлежащих к списку телефонов этих парней.

пытаться

найти всех людей, у которых есть этот телефон в списке.

это, однако, не без каких-либо дополнительных затрат. фонотектор для каждого пользователя много хранится и индексируется.

 class User(ndb.Model): phoneList = ndb.PropertyList() phone_id= ndb.StringProperty() select from where User.phoneList = :this_phone_number