8

appengineデータストアからの現在のクエリの効率を改善しようとしています。現在、同期方式を使用しています。

class Hospital(ndb.Model):
      name = ndb.StringProperty()
      buildings= ndb.KeyProperty(kind=Building,repeated=True)
class Building(ndb.Model):
      name = ndb.StringProperty()
      rooms= ndb.KeyProperty(kind=Room,repeated=True)
class Room(ndb.Model):
      name = ndb.StringProperty()
      beds = ndb.KeyProperty(kind=Bed,repeated=True)
class Bed(ndb.Model):
      name = ndb.StringProperty()
      .....

現在、私はばかげています:

currhosp = ndb.Key(urlsafe=valid_hosp_key).get()
nbuilds = ndb.get_multi(currhosp.buildings)
for b in nbuilds:
   rms = ndb.get_multi(b.rooms)
   for r in rms:
      bds = ndb.get_multi(r.beds)
      for b in bds:
          do something with b object

get_multi_asyncを使用して、これをはるかに高速なクエリに変換したいと思います

私の難しさは、これをどのように行うことができるかということです。何か案は?

最高のジョン

4

3 に答える 3

11

上記の構造を使用することで可能であり、一連のタスクレットでこれを解決できることが確認されました。これは、反復法よりも大幅に高速化されています

@ndb.tasklet
def get_bed_info(bed_key):
    bed_info = {}
    bed = yield bed_key.get_async()
    format and store bed information into bed_info
    raise ndb.Return(bed_info)

@nbd.tasklet
def get_room_info(room_key):
    room_info = {}
    room = yield room_key.get_async()
    beds = yield map(get_bed_info,room.beds)
    store room info in room_info
    room_info["beds"] = beds
    raise ndb.Return(room_info)

@ndb.tasklet
def get_building_info(build_key):
    build_info = {}
    building = yield build_key.get_async()
    rooms = yield map(get_room_info,building.rooms)
    store building info in build_info
    build_info["rooms"] = rooms
    raise ndb.Return(build_info)

@ndb.toplevel
def get_hospital_buildings(hospital_object):
    buildings = yield map(get_building_info,hospital_object.buildings)
    raise ndb.Return(buildings)

ここで、病院オブジェクト(病院)がある病院機能からのメインコールが来ます。

hosp_info = {}
buildings = get_hospital_buildings(hospital_obj)
store hospital info in hosp_info
hosp_info["buildings"] = buildings
return hosp_info

どうぞ!それは信じられないほど効率的であり、スケジュールがGAEバックボーン内で可能な限り最速の方法ですべての情報を完了することを可能にします。

于 2013-01-14T06:13:36.917 に答える
3

query.map()で何かを行うことができます。https://developers.google.com/appengine/docs/python/ndb/async#taskletsおよびhttps://developers.google.com/appengine/docs/python/ndb/queryclass#Query_mapを参照してください

于 2013-01-11T16:01:32.417 に答える
-1

それは不可能だ。2番目のクエリ(ndb.get_multi(b.rooms))は、最初のクエリの結果によって異なります。したがって、この時点で最初のクエリの(最初の)結果がとにかく利用可能でなければならないので、それを非同期にプルすることは機能しません。NDBは、バックグラウンドでそのようなことを行います(最初の結果を処理している間、ndb.get_multi(currhosp.buildings)の次のアイテムを既にバッファリングします)。ただし、非正規化を使用することもできます。つまり、Building-Room-Bedペアごとに1つのエントリを持つ大きなテーブルを保持し、そのテーブルから結果を取得できます。このテーブルへの書き込みよりも読み取りが多い場合は、速度が大幅に向上します(3ではなく1 DB読み取り)。

于 2013-01-11T12:01:44.017 に答える