manniru
12/10/2016 - 10:08 AM

GAE Search-augmented NDB Models: Keep a searchable index up-to-date with the latest information in your datastore Models.

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'