App Engine Datastore INオペレーター-使用方法
-
05-07-2019 - |
質問
読書: 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)
しかし、それはキーのリストを取得します。そのリストを取得してクエリに取得し、UniqueListOfSavedItemsからstrフィールドを取得します。できると思った:
q2 = db.Gql("SELECT * FROM UniqueListOfSavedItems WHERE := str in q")
しかし、何かが正しくない...何かアイデアはありますか?それは(私の仕事にいるので、今これをテストすることはできません):
q2 = db.Gql("SELECT * FROM UniqueListOfSavedItems __key__ := str in q)
サイドノート:私が本当に気にしているのは、「IN」演算子。
解決
キーのリストがあるので、2番目のクエリを実行する必要はありません-代わりにバッチフェッチを実行できます。これを試してください:
#and this should get me the items that a user saved
useritems = db.get(saveditemkeys)
(ガード句さえ必要ないことに注意してください-0エンティティのdb.getは適切に短絡されます。)
違いは何ですか、尋ねることができますか?さて、db.getは約20〜40ミリ秒かかります。一方、クエリ(GQLかどうか)には約160〜200ミリ秒かかります。しかし、待ってください、悪化します! IN演算子はPythonで実装され、複数のクエリに変換され、シリアルに実行されます。したがって、10個のキーに対してINフィルターを使用してクエリを実行すると、合計で約1.6秒の遅延で、160ミリ秒程度のクエリ操作が10回実行されます。対照的に、単一のdb.getは同じ効果があり、合計で約30ミリ秒かかります。
他のヒント
+1で私を正しい方向に導いてくれたAdamに。彼の指針に基づいて、コード検索で検索を行うと、次の解決策があります。
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)