【问题标题】:GAE: Efficiently querying entities and their referenced entitiesGAE:高效查询实体及其引用的实体
【发布时间】:2016-06-08 19:36:34
【问题描述】:

我试图在模板视图中有效地返回实体列表以及它们各自引用的实体。例如

我们正在使用两种类型:

class Event(ndb.Model):
    """An fun activity or event"""
    name = ndb.StringProperty()
    venue = ndb.KeyProperty()

class Venue(ndb.Model):
    """The venue of an event"""
    name = ndb.StringProperty()
    address = StringProperty()

Event 类通过 ndb.KeyProperty() 引用 Venue。要将活动列表及其各自的场地显示到模板中,我可以先执行以下查询:

# we can fetch this from memcache
events = Event.query().fetch()

那么,在我看来:

{% for event in events %}
    Event Name: {{event.name}}
    Event Venue: {{event.venue.get().name}}  # is this line costly?
{% endfor %}

使用这种方法,我认为对于每个活动,都会有get() 呼叫其各自的场地。如果这是真的,那听起来很昂贵。假设有 100 个事件。每个页面加载将产生 100 个event.venue.get().name 请求。这意味着每天适度的 10000 次页面浏览会引发 10000 * 100 .get() 请求。听起来对吗?

这是解决这个问题的最佳方法吗?如果没有,我可以考虑哪些选择?

【问题讨论】:

    标签: google-app-engine google-cloud-datastore app-engine-ndb


    【解决方案1】:

    首先,根据数据集中的场所总数,它们可能都可以轻松放入 Memcache。因此,除非修改了场地,否则您可以连续数天不接触数据存储区——无论页面浏览量如何。确保您也将 Memcache 用于您的场所。

    其次,一种更有效的检索实体的方法是在批处理请求中。循环浏览您的活动,创建您需要的所有场地的列表(顺便说一下,如果多个活动在同一个场地发生,这可能小于活动的数量 - 我没有看到您的代码中的检查),然后为所有场所发出批处理请求。

    【讨论】:

    • 您能否在代码中显示批量检索场地后如何将每个场地与每个事件匹配?
    【解决方案2】:

    这是获取所有场地名称的 Python 代码:

    venue_keys = set(event.venue for event in events)
    venues = ndb.get_multi(venue_keys)
    venue_name = {venue.key, venue.name for venue in venues}
    

    然后,在您的模板中,您可以使用:

    Event Venue: {{ venue_name.get(event.venue, 'No venue') }}
    

    【讨论】:

    • 太棒了!现在我可以从 memcache 中检索所有事件和场地!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 2016-10-16
    相关资源
    最近更新 更多