エンコードされたキーをAppengineの短い識別子にマッピングします
-
04-10-2019 - |
質問
クライアントが特定のオブジェクトを参照できるように、クライアントに一意の参照を送信したいと思います。 Appengineが提供するエンコードされたキーは、50バイトの長さである場合があり、おそらく2つまたは3つのバイトしか必要ありません(4つか5つを必要とすることを望んでいますが、しばらくはそうではありません!)。
一度に400の参照を送信する可能性があるため、大きなキーを送信することは実際には非常に高価です。
したがって、これらの長いキーをはるかに短いキーにマッピングしたいと思います。明らかな解決策は、データストアにマッピングを保存することですが、400個のオブジェクトを送信するときは、400個の追加クエリを行っていますよね? Memcacheのマッピングのコピーを保持することで、費用を軽減するかもしれません。より良い方法はありますか?
Appengineが作成して使用するエンコードされていないキーから数字を削除できますか?アプリ全体ではなく、エンティティの種類ごとに一意にするために使用するIDのみが必要です。
ありがとう、
ライリー
解決
DataStoreキーには、アプリIDのように、必要のない追加の情報が含まれています。したがって、あなたは間違いなく送信する必要はありません 全体 キー。
これらの参照がDataStoreの特定の種類の場合、さらに良くなり、Key_NameまたはNumeric IDを送信することができます(キーが使用する場合はどちらか)。後者の場合は、各キーを数バイトで送信できます(特定のケースでよりコンパクトなものに応じて、可変長または固定長の整数エンコードを選択できます[おそらく前者はまで送信しているIDのほとんどは非常に大きくなります])。
ユーザーからこれらの部分キーを受け取った場合、データストアからエンティティを取得するために必要な完全なキーを簡単に再構築できます。 Pythonランタイムを使用している場合は、使用できます db.Key.from_path(kind_name, numeric_id_or_key_name)
.
このようなスキームは、DataStore/Memcacheを使用してカスタムマッピングを保存しようとするよりも、より簡単で(多く)より速くする必要があります。
他のヒント
カスタムマッピングメカニズムは必要ありません。エンティティキー名を使用して、短い識別子を保存します。
entity = MyKind(key_name=your_short_id)
entity.put()
次に、これらの短い識別子を1つのクエリで取得できます。
keys = MyKind.all(keys_only=True).filter(...).fetch(400)
short_ids = [key.name() for key in keys]
最後に、使用します MyKind.get_by_key_name(short_id)
ユーザーから送信された識別子からエンティティを取得するため。