App Engine Datastore IN Operator - как использовать? - PullRequest
3 голосов
/ 16 июня 2009

Чтение: http://code.google.com/appengine/docs/python/datastore/gqlreference.html

Я хочу использовать:

: = IN

но я не уверен, как заставить это работать. Давайте предположим следующее

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".

Ответы [ 2 ]

10 голосов
/ 17 июня 2009

Поскольку у вас есть список ключей, вам не нужно делать второй запрос - вместо этого вы можете выполнить пакетную выборку. Попробуйте это:

#and this should get me the items that a user saved
useritems = db.get(saveditemkeys)

(Обратите внимание, что вам даже не нужно выражение охраны - db.get для 0 сущностей замкнут накоротко).

В чем разница, спросите вы? Ну, db.get занимает около 20-40 мс. С другой стороны, запрос (GQL или нет) занимает около 160-200 мс. Но подождите, это становится хуже! Оператор IN реализован в Python и транслируется в несколько запросов, которые выполняются последовательно. Поэтому, если вы выполняете запрос с фильтром IN для 10 ключей, вы выполняете 10 отдельных операций запроса 160 мс с общей задержкой около 1,6 секунды. Напротив, один db.get будет иметь такой же эффект и займет в общей сложности около 30 мс.

0 голосов
/ 17 июня 2009

+ 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...