Search¶
Ferris provides integration into App Engine’s search api by providing utilities for indexing models and for retrieving model instances from results.
Indexing Models¶
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()
- class ferris.behaviors.searchable.Searchable(Model)[source]¶
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')
- SearchableMeta.search_index¶
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
- SearchableMeta.search_fields¶
A list or tuple of field names to use when indexing. If not specified, all fields will be used.
- SearchableMeta.search_exclude¶
A list or tuple of field names to exclude when indexing.
- SearchableMeta.search_callback¶
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.
Performing Searches¶
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 indexing 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.
- class ferris.components.search.Search(controller)[source]¶
Provides a simple high-level interface to searching items in the App Engine Search API and utilizes the search helpers in ferris.core.search.
- Search.search()[source]¶
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')
)
Macros¶
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 %}
- SearchMacros.filter(uri, examples=None, _pass_all=False)¶
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'))}}
- SearchMacros.info()¶
Displays information about the search. If the search returns no results or if the user submits an invalid query, it 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 modify as needed.
Advanced Usage¶
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.
- ferris.core.search.index_entity(instance, index, only=None, exclude=None, extra_converters=None, indexer=None, callback=None)[source]¶
Adds an Model instance into full-text search indexes.
Parameters: - instance – an instance of ndb.Model
- only (list(string)) – If provided, will only index these fields
- exclude (list(string)) – If provided, will not index any of these fields
- extra_converters (dict) – Extra map of property names or types to converter functions.
- indexer – A function that transforms properties into search index fields.
- callback – A function that will recieve (instance, fields). Fields is a map of property names to search.Field instances generated by the indexer the callback can modify this dictionary to change how the item is indexed.
This is usually done in Model.after_put, for example:
def after_put(self): index(self)
- ferris.core.search.unindex_entity(instance_or_key, index=None)[source]¶
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)
- ferris.core.search.search(index, query, limit=None, cursor=None, options=None, sort_field=None, sort_direction='asc', sort_default_value=None, per_document_cursor=False, transformer=<function transform_to_entities at 0x10e148848>)[source]¶
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.