Избегание фильтра в хранилище данных AppEngine

#google-app-engine #google-cloud-platform #google-cloud-datastore #query-optimization

#google-app-engine #google-облачная платформа #google-облако-хранилище данных #оптимизация запросов

Вопрос:

У меня есть два объекта в хранилище данных Google:

A:

 id,  
name,  
.... a lot of other columns
  

B:

 id,  
Key(A, <id_of_A_record>) --> Reference Property A,  
URL,  
size  
... and more columns
  

У меня есть куча идентификаторов, и я хочу запросить эти идентификаторы.
Теперь я могу добиться этого с помощью

 A_ids = [1, 2, 3, 4, 5, 6]
B.all().filter('A IN', A_ids).fetch(None)
  

Однако, если имеется 6 идентификаторов A_id, существует 6 вызовов db, что превосходит цель IN . Могу ли я каким-либо образом добиться этого, избегая фильтра IN (слишком много вызовов DB)?

Спасибо!

Ответ №1:

На самом in деле фильтр — это просто удобная функция, предоставляемая вашим ORM. За кулисами он выполняет ряд действий OR , чтобы это произошло.

Имя фильтра в (value1, …, valueN) преобразуется в (name = value1) ИЛИ … ИЛИ (name = valueN) (также дизъюнкционный узел)

https://googleapis.dev/python/python-ndb/latest/query.html#google.cloud.ndb.query .FilterNode

Даже OR s не поддерживаются самим хранилищем данных, оно просто эмулируется клиентской библиотекой:

Природа механизма индексных запросов накладывает определенные ограничения на то, что может делать запрос. Запросы в режиме хранилища данных не поддерживают совпадения подстрок, совпадения без учета регистра или так называемый полнотекстовый поиск. Операторы NOT, OR и != изначально не поддерживаются, но некоторые клиентские библиотеки могут добавить поддержку поверх режима хранилища данных.

https://cloud.google.com/datastore/docs/concepts/queries#restrictions_on_queries

Я думаю, что клиентская библиотека выполняет OR s, запуская отдельные запросы, поэтому вы видите эти вызовы 6 db. Я не думаю, что вы сможете избежать этого без реструктуризации ваших данных.