将 GAE 的搜索 API 与 ndb 的 tasklet 结合使用

Using GAE's search API with ndb's tasklets

GoogleAppEngine 搜索API可以returnasynchronous results. The docs say very little about these futures, but they do have a .get_result() method which looks a lot like an ndb.Future。我认为尝试在 tasklet 中使用一个会很有趣:

@ndb.tasklet
def async_query(index):
    results = yield [index.search_async('foo'), index.search_async('bar')]
    raise ndb.Return(results)

不幸的是,这不起作用。 ndb 不喜欢这个,因为搜索 API 的未来 return 似乎与 ndb.Future 不兼容。但是,tasklet 文档还特别提到它们已与 urlfetch futures 一起使用。有没有办法通过搜索获得类似的行为 api?

事实证明 一种方法来完成这项工作(至少,我在 dev_appserver 上的测试似乎通过了 ;-)。

@ndb.tasklet
def async_query(index, query):
    fut = index.search_async(query)
    yield fut._rpc
    raise ndb.Return(fut._get_result_hook())

现在,如果我想执行多个查询并混合一些数据存储查询(即我可能使用搜索 API 来获取模型实体的 ID),

@ndb.tasklet
def get_entities(queries):
    search_results = yield [async_query(q) for q in queries]
    ids = set()
    for search_result in search_results:
        for doc in search_results.results:
            ids.add(doc.doc_id)
    entities = yield [FooModel.get_by_id_async(id_) for id_ in ids_]
    raise ndb.Return(entities)

这太hacky了——我怀疑它是否得到官方支持,因为我使用的是异步搜索结果的内部成员class ...使用风险自负:-)。