我正在尝试从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
将其转换为更快的查询我的困难在于如何做到这一点? 有什么想法吗?
最佳乔恩
答案 0 :(得分:11)
使用上面给定的结构,有可能,并确认您可以使用一组tasklet解决此问题。与迭代方法相比,这是一个 SIGNIFICANT 加速。
@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主干内以最快的方式完成所有信息。
答案 1 :(得分:3)
您可以使用query.map()执行某些操作。请参阅https://developers.google.com/appengine/docs/python/ndb/async#tasklets和https://developers.google.com/appengine/docs/python/ndb/queryclass#Query_map
答案 2 :(得分:-1)
不可能。 您的第二个查询(ndb.get_multi(b.rooms))取决于您的第一个查询的结果。 所以拉动它的async dosnt工作,因为此时第一个查询的(第一个)结果无论如何都必须是可用的。 NDB在后台执行类似的操作(在处理第一个结果时,它已经缓冲了ndb.get_multi(currhosp.buildings)的下一项)。 但是,你可以使用非规范化,即保持一个大表,每个Building-Room-Bed对有一个条目,并从该表中提取结果。 如果您有更多读取而不是写入此表,这将使您获得巨大的速度提升(1 DB读取,而不是3)。