Skip to content

Instantly share code, notes, and snippets.

@erichiggins
Created April 29, 2014 19:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save erichiggins/f2260490c72c077d2ccb to your computer and use it in GitHub Desktop.
Save erichiggins/f2260490c72c077d2ccb to your computer and use it in GitHub Desktop.
GAE Search-augmented NDB Models: Keep a searchable index up-to-date with the latest information in your datastore Models.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Search-augmented NDB Models for Google App Engine.
Usage:
import search_models
# Define an index for the document type.
PEOPLE_INDEX = search.Index(name='people')
# Define a `_document` property on the Model and add the hooks.
class Person(ndb.Model):
first_name = ndb.StringProperty()
last_name = ndb.StringProperty()
full_name = ndb.ComputedProperty(lambda self: self.first_name + ' ' + self.last_name)
birthday = ndb.DateProperty()
...
@property
def _document(self):
return search.Document(doc_id=self.key.id(), fields=[
search.TextField(name='first', value=self.first_name),
search.TextField(name='last', value=self.last_name),
search.TextField(name='name', value=self.full_name),
search.TextField(name='first', value=self.first_name),
search.DateField(name='birthday', value=self.birthday),
...
])
def _post_put_hook(self, future):
PEOPLE_INDEX.put(self._document)
@classmethod
def _post_delete_hook(cls, key, future):
PEOPLE_INDEX.delete(key.string_id())
# Handle search requests
class SearchHandler(webapp2.RequestHandler):
def get(self, *args, **kwargs):
query = self.request.get('query')
cursor = self.request.get('cursor', '')
results = self.do_search(query, cursor)
instances = self.format_documents(results.results)
self.render(instances)
def do_search(self, query, cursor=None):
query_opts = search.QueryOptions(limit=15)
query_instance = search.Query(query_string=query, options=query_opts)
return PEOPLE_INDEX.search(query_instance)
def format_documents(self, documents):
results = []
for doc in documents:
fmt_doc = {'id': doc.doc_id}
for field in doc.fields:
fmt_doc[field.name] = field.value
results.append(fmt_doc)
return results
"""
__author__ = 'Eric Higgins'
__copyright__ = 'Copyright 2013, Eric Higgins'
__version__ = '0.0.1'
__email__ = 'erichiggins@gmail.com'
__status__ = 'Development'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment