Хранилище данных App Engine В Operator - как использовать?
-
05-07-2019 - |
Вопрос
Чтение: http://code.google.com/appengine/docs/python/datastore/gqlreference.html
Я хочу использовать:
:= В
но я не уверен, как заставить это работать.Давайте предположим следующее
class User(db.Model):
name = db.StringProperty()
class UniqueListOfSavedItems(db.Model):
str = db.StringPropery()
datesaved = db.DateTimeProperty()
class UserListOfSavedItems(db.Model):
name = db.ReferenceProperty(User, collection='user')
str = db.ReferenceProperty(UniqueListOfSavedItems, collection='itemlist')
Как я могу выполнить запрос, который выдаст мне список сохраненных элементов для пользователя?Очевидно, что я могу это сделать:
q = db.Gql("SELECT * FROM UserListOfSavedItems WHERE name :=", user[0].name)
но это дает мне список ключей.Теперь я хочу взять этот список и вставить его в запрос, чтобы получить поле str из UniqueListOfSavedItems.Я думал, что смогу это сделать:
q2 = db.Gql("SELECT * FROM UniqueListOfSavedItems WHERE := str in q")
но что-то не так...есть идеи?Это (я на своей повседневной работе, поэтому не могу проверить это сейчас):
q2 = db.Gql("SELECT * FROM UniqueListOfSavedItems __key__ := str in q)
боковое примечание:какая дьявольски сложная проблема для поиска, потому что все, что меня действительно волнует, - это оператор "IN".
Решение
Поскольку у вас есть список ключей, вам не нужно выполнять второй запрос - вместо этого вы можете выполнить пакетную выборку.Попробуй это:
#and this should get me the items that a user saved
useritems = db.get(saveditemkeys)
(Обратите внимание, что вам даже не нужно предложение guard - db.get для объектов 0 имеет соответствующее короткое замыкание.)
В чем разница, спросите вы?Ну, получение db.get занимает около 20-40 мс.С другой стороны, запрос (GQL он или нет) занимает около 160-200 мс.Но подождите, будет еще хуже!Оператор IN реализован на Python и преобразуется в несколько запросов, которые выполняются последовательно.Таким образом, если вы выполняете запрос с фильтром IN для 10 ключей, вы выполняете 10 отдельных операций запроса продолжительностью 160 мс с общей задержкой около 1,6 секунды.Напротив, один db.get будет иметь тот же эффект и займет в общей сложности около 30 мс.
Другие советы
+1 Адаму за то, что наставил меня на правильный путь.Основываясь на его указателе и выполнив некоторый поиск в Code Search, у меня есть следующее решение.
usersaveditems = User.Gql(“Select * from UserListOfSavedItems where user =:1”, userkey)
saveditemkeys = []
for item in usersaveditems:
#this should create a list of keys (references) to the saved item table
saveditemkeys.append(item.str())
if len(usersavedsearches > 0):
#and this should get me the items that a user saved
useritems = db.Gql(“SELECT * FROM UniqueListOfSavedItems WHERE __key__ in :1’, saveditemkeys)