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

using the given structures above, it is possible, and was confirmed that you can solve this with a set of tasklets. It is a SIGNIFICANT speed up over the iterative method.

@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)

Now comes the main call from the hospital function where you have the hospital object (hosp).

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

There you go! It is incredibly efficient and lets the schedule complete all the information in the fastest possible manner within the GAE backbone.

于 2013-01-14T06:13:36.917 回答
3

你可以用 query.map() 做一些事情。请参阅https://developers.google.com/appengine/docs/python/ndb/async#taskletshttps://developers.google.com/appengine/docs/python/ndb/queryclass#Query_map

于 2013-01-11T16:01:32.417 回答
-1

不可能。您的第二个查询 (ndb.get_multi(b.rooms)) 取决于您的第一个查询的结果。所以拉它异步dosnt工作,因为此时第一个查询的(第一个)结果无论如何都必须可用。NDB 在后台执行类似的操作(在您处理第一个结果时,它已经缓冲了 ndb.get_multi(currhosp.buildings) 的下一项)。但是,您可以使用非规范化,即保留一个大表,每个 Building-Room-Bed 对有一个条目,然后从该表中提取结果。如果您对该表的读取次数多于写入次数,这将大大提高您的速度(读取 1 个 DB,而不是 3 个)。

于 2013-01-11T12:01:44.017 回答