Ferris provides integration into App Engine’s search api by providing utilities for indexing models and for retrieving model instances from results.
The Searchable behavior will automatically add entities to the search index when saved. This is a wrapper around index_entity():
from ferris import Model
from ferris.behaviors import searchable
class Post(Model):
class Meta:
behaviors = (searchable.Searchable,)
title = ndb.StringProperty()
context = ndb.TextProperty()
Automatically indexes models during after_put into the App Engine Text Search API.
This behavior can be configured using the meta class:
class Meta:
behaviors = (searchable.Searchable,)
search_index = 'auto_ix_Post'
search_exclude = ('thumbnail', 'likes')
Which search index to add the entity’s data to. By default this is auto_ix_[Model]. You can set it to a list or tuple to add the entity data to muliple indexes
A list or tuple of field names to use when indexing. If not specified, all fields will be used.
A list or tuple of field names to exclude when indexing.
A callback passed to index_entity(). This can be used to index additional fields:
from google.appengine.ext import ndb, search
from ferris.behaviors.searchable import Searchable
class Post(Model):
class Meta:
behaviors = (Searchable,)
@static_method
def search_callback(instance, fields):
category = instance.category.get()
fields.append(
search.TextField(
name="category",
value=category.title
)
)
title = ndb.StringProperty()
category = ndb.KeyProperty(Category)
Note
The searchable behavior can not automatically index Computed, Key, or Blob properties. Use the search_callback to implement indexing for these fields.
The most common use case for search is to present search results to the user. The Search component provides a wrapper around search() to make querying and index and transforming the results into ndb entities easy:
from ferris import Controller
from ferris.components.search import Search
class Posts(Controller):
class Meta:
components = (Search,)
def list(self):
return self.components.search()
This component plays well with scaffolding, pagination, and messages.
Provides a simple high-level interface to searching items in the App Engine Search API and utilizes the search helpers in ferris.core.search.
Searches using the provided index (or an automatically determine one).
Expects the search query to be in the query request parameter.
Also takes care of setting pagination information if the pagination component is present.
See ferris.core.search.search() for more details.
When searching, the component:
- Determines the index to search.
- If pagination is used, gets the cursor.
- Performs the search using search().
- Transforms the results into ndb entities.
- Sets pagination data
- Sets search_query and search_results in the view context.
You can pass in configuration to component when calling search():
@route
def list(self):
self.components.search(
'global',
query=self.request.params.get('query')
)
The search macros make it easy to interact with the search component from your templates.
Import the search macros using:
{% import "macros/search.html" as search with context %}
Displays a simple search box. If the search action is different from the current action be sure to specify a URI (i.e. for global search):
{{search.filter(uri('posts:search'))}}
Displays information about the search. If the search returns no results or if the user submits an invalid query will display a friendly message to the user.
If the look and feel of the search macros needs to be customized for your application, feel free to copy them into app/templates/macros/search.html and modified as needed.
The search module provides the functionality that’s wrapped by the searchable behavior and the search component. You can use this directly to have greater control over how things are indexed or search. You can also use search() directly to search outside of a controller context.
Adds an Model instance into full-text search indexes.
Parameters: |
|
---|
This is usually done in Model.after_put, for example:
def after_put(self):
index(self)
Removes a document from the full-text search.
This is usually done in Model.after_delete, for example:
@classmethod
def after_delete(cls, key):
unindex(key)
Searches an index with the given query.
By default, this will transform the results into a list of datastore entities. This behavior can be override by providing a function to the transformer argument.
Additionally, this only gets document ids by default. To override this, pass in an options parameter that sets ids_only to False.
example of disabling both of these default behaviors:
search(index=’test_index’, query=’test’, options={‘ids_only’: False}, transformer=list)
This function returns a tuple: error, results, cursor, next_cursor.