Mapping types and Indexables

The MappingType class

elasticutils.MappingType lets you centralize concerns regarding documents you’re storing in your Elasticsearch index.

Lets you tie business logic to search results

When you do searches with MappingTypes, you get back those results as an iterable of MappingTypes by default.

For example, say you had a description field and wanted to have a truncated version of it. You could do it this way:

class MyMappingType(MappingType):

    # ... missing code here

    def description_truncated(self):
        return self.description[:100]

results = S(MyMappingType).query(description__text='stormy night')

print list(results)[0].description_truncated()


The most basic MappingType is the DefaultMappingType which is returned if you don’t specify a MappingType and also don’t call elasticutils.S.values_dict() or elasticutils.S.values_list(). The DefaultMappingType lets you access search result fields as instance attributes or as keys:


The latter syntax is helpful when there are attributes defined on the class that have the same name as the document field or aren’t valid Python names.

For more information

See Types and Mappings for documentation on defining mappings in the index.

See elasticutils.MappingType for documentation on creating MappingTypes.

The Indexable class

elasticutils.Indexable is a mixin for elasticutils.MappingType that has methods and classmethods for making indexing easier.


Here’s an example of a class that subclasses MappingType and Indexable. It’s based on a model called BlogEntry.

class BlogEntryMappingType(MappingType, Indexable):
    def get_index(cls):
        return 'blog-index'

    def get_mapping_type_name(cls):
        return 'blog-entry'

    def get_model(cls):
        return BlogEntry

    def get_es(cls):
        return get_es(urls=['http://localhost:9200'])

    def get_mapping(cls):
        return {
            'properties': {
                'id': {'type': 'integer'},
                'title': {'type': 'string'},
                'tags': {'type': 'string'}

    def extract_document(cls, obj_id, obj=None):
        if obj == None:
            obj = cls.get_model().get(id=obj_id)

        doc = {}
        doc['id'] =
        doc['title'] = obj.title
        doc['tags'] = obj.tags
        return doc

    def get_indexable(cls):
        return cls.get_model().get_objects()

With this, I can write code elsewhere in my project that:

  1. gets the mapping type name and mapping for documents of type “blog-entry”
  2. gets all the objects that are indexable
  3. for each object, extracts the Elasticsearch document data and indexes it

When I create my elasticutils.S object, I’d create it like this:

s = S(BlogEntryMappingType)

and now by default any search results I get back are instances of the BlogEntryMappingType class.