Search code examples
google-app-enginegoogle-cloud-datastoreapp-engine-ndb

GAE: Efficiently querying entities and their referenced entities


I am trying to efficiently return a list of entities, and their respective referenced entities in a template view. For example

We are working with two Kinds:

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

The Event kind references Venue via an ndb.KeyProperty(). To display a list of events and their respective venues into a template, I can first do this query:

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

Then, in my view:

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

With this method, I think that for each event, there will be get() call for its respective venue. If this is true, it sounds expensive. Assuming that there are 100 events. Each page load would incur 100 event.venue.get().name requests. This means that a modest 10000 page views per day would incur 10000 * 100 .get() requests. Does that sound correct?

Is this the best approach to this problem? If not, what options can I consider?


Solution

  • First, depending on the total number of venues in your dataset, they may all easily fit into Memcache. So unless a venue is modified, you can go for days without touching the datastore - regardless of the number of page views. Make sure you use Memcache for your venues too.

    Second, a more efficient way to retrieve entities is in a batch request. Loop through your events, create a list of all venues that you need (by the way, which may be smaller than the number of events if several events happen in the same venue - I don't see that check in your code), then issue a batch request for all venues.