2009-06-16 2 views
3

Reading: http://code.google.com/appengine/docs/python/datastore/gqlreference.htmlApp Engine Datastore IN Operator - как использовать?

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

: = В

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

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» оператор.

ответ

9

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

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

(. Примечание вы даже не нужен пункт охраны - это db.get на 0 сущностей закорочен appropritely)

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

+0

Какой прекрасный ответ ... Я воплощу это сегодня вечером. Я получил код работает (да!), Поэтому оптимизация может прийти позже. :) Сейчас я на регулярных выражениях. Трахающиеся. Глава. На. Клавиатура. –

+1

Брэндон - я использую приложение под названием regexbuddy, которое очень помогает. Не связаны с ними каким-либо образом. –

0

+1 Адаму для того, чтобы получить меня на правильном пути. Основываясь на его указателе и выполняя поиск в поиске кода, у меня есть следующее решение.

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) 
Смежные вопросы