NAME

Elastic::Model::TypeMap::Base - A base class for all TypeMaps

VERSION

version 0.52

SYNOPSIS

Define your own type map

package MyApp::TypeMap;

use Elastic::Model::TypeMap::Base qw(
    Elastic::Model::TypeMap::Default
);

has_type 'MyCustomType',
    deflate_via { sub { ... }},
    inflate_via { sub { ... }},
    map_via     { type => 'string' };

# Inlined in/deflation
has_type 'MyCustomType',
    deflate_via { '$val * 1000'},
    inflate_via { '$val / 1000'},
    map_via     { type => 'string' };

Use your type map by declaring it in your Model

package MyApp;

use Elastic::Model;

has_namespace 'myapp', {
    user => 'MyApp::User',
    post => 'MyApp::Post'
};

has_typemap 'MyApp::TypeMap';

DESCRIPTION

Moose's type constraints and introspection allows Elastic::Model to figure out how to map your data model to the Elasticsearch backend with the minimum of effort on your part.

What YOU need to do is: Be specific about the type constraint for each attribute.

For instance, if you have an attribute called count, then specify the type constraint isa => 'Int'. That way, we know how to define the field in Elasticsearch, and how to deflate and inflate the value.

Type constraints can inherit their mapping, inflator and deflator from their parent type-constraints. For instance, if you were to assign count the type constraint PositiveInt, although we don't know about that constraint, we do know about its parent, Int, so we could still handle the field correctly.

Type maps are used to define:

  • what mapping Elastic::Model will generate for each attribute when you create an index or update the mapping of an existing index.

  • how Elastic::Model will deflate and inflate each attribute when saving or retrieving docs stored in Elasticsearch.

BUILT-IN TYPE MAPS

See Elastic::Model::TypeMap::Default for the type-maps provided by default in Elastic::Model.

DEFINING YOUR OWN TYPE MAP

If you define your own types which need custom mapping or custom deflators/inflators then you can add these definitions in your own type-map, while still falling back to the built-in type-maps for other types.

First, you need to name your type map class:

package MyApp::TypeMap;

Then import the helper functions from Elastic::Model::TypeMap::Base and load any other typemaps that you want to inherit from:

use Elastic::Model::TypeMap::Base qw(
    Elastic::Model::TypeMap::Default
    Useful::TypeMap::From::CPAN
);

Now you can define your type maps:

has_type 'MyCustomType',
    deflate_via { sub { ... }},
    inflate_via { sub { ... }},
    map_via     { type => 'string' };

The type name passed to has_type should be a string, eg 'Str' for the core Moose string type, or the fully qualified name for the types you have defined with MooseX::Types, eg 'MyApp::Types::SomeType'.

deflate_via and inflate_via each expect a coderef which, when called returns a coderef:

sub {
    my ($type_constraint, $attr, $typemap_class) = @_;
    return sub {
        my ($val) = @_;
        return do_something($val)
    }
}

Alternatively, the deflate_via and inflate_via coderefs can, when executed, return a string of Perl code which can be inlined for more efficient flation. Both the inflator and deflator are passed the value that needs to be converted in $val. For instance:

has_type 'MyDateType',
    deflate_via { '$val->to_string'            },
    inflate_via { 'My::Date::Class->new($val)' },
    map_via     { 'type' => 'date'             };

map_via expects a coderef which returns the mapping for that type as a list, not as a hashref:

sub {
    my ($type_constraint, $attr, $typemap_class) = @_;
    return (type => 'string', ..... );
}

A simple example

Here is an example of how to define a type map for DateTime objects:

use DateTime;

has_type 'DateTime',

deflate_via {
    sub { $_[0]->set_time_zone('UTC')->iso8601 };
},

inflate_via {
    sub {
        my %args;
        @args{ (qw(year month day hour minute second)) } = split /\D/, shift;
        DateTime->new(%args);
    };
},

map_via { type => 'date' };

An inlined example:

use DateTime;

has_type 'DateTime',

deflate_via { '$val->set_time_zone("UTC")->iso8601' },
inflate_via {
     'do {'
   . '  my %args;'
   . '  @args{ (qw(year month day hour minute second)) } = split /\D/, $val;'
   . '  DateTime->new(%args);'
   . '}'
},

map_via { type => 'date' };

ATTRIBUTES

It is unlikely that you will need to know about any of these attributes, but they are documented here for completeness.

deflators

$deflators = $class->deflators

Returns a hashref of all deflators known to $class.

inflators

$inflators = $class->inflators

Returns a hashref of all inflators known to $class.

mappers

$mappers = $class->mappers

Returns a hashref of all mappers known to $class.

typemap

$map = $class->typemap

Returns a hashref containing the "deflators", "inflators" and "mappers" known to $class.

METHODS

It is unlikely that you will need to know about any of these methods, but they are documented here for completeness.

Elastic::Model::TypeMap::Base only has class methods, no instance methods, and no new().

find_deflator()

$deflator = $class->find_deflator($attr)

Returns a coderef which knows how to deflate $attr, or throws an exception. Any inlined deflators are eval'ed into an anonymous sub.

find_raw_deflator()

$deflator = $class->find_deflator($attr)

Returns a coderef which knows how to deflate $attr, or throws an exception. Any inlined deflators are returned as strings.

find_inflator()

$inflator = $class->find_inflator($attr)

Returns a coderef which knows how to inflate $attr, or throws an exception. Any inlined inflators are eval'ed into an anonymous sub.

find_raw_inflator()

$inflator = $class->find_inflator($attr)

Returns a coderef which knows how to inflate $attr, or throws an exception. Any inlined inflators are returned as strings.

find_mapper()

$mapping = $class->find_mapper($attr)

Returns a mapping for $attr, or throws an exception.

find()

$result = $class->find($thing, $type_constraint, $attr);

Finds a $thing (deflator, inflator, mapper) or returns undef.

class_deflator()

$deflator = $class->class_deflator( $class_to_deflate, $attrs );

Returns a coderef which knows how to deflate an object of class $class_to_deflate, including the attributes listed in $attr (or all attributes if not specified).

class_inflator()

$inflator = $class->class_inflator( $class_to_inflate, $attrs );

Returns a coderef which knows how to inflate deflated data for class $class_to_inflate, including the attributes listed in $attr (or all attributes if not specified).

class_mapping()

$mapping = $class->class_mapping( $class_to_map, $attrs );

Returns a hashref of the mapping for class $class_to_map, including the attributes listed in $attr (or all attributes if not specified).

attribute_mapping()

$mapping = $class->attribute_mapping($attr);

Returns a hashref of the mapping for attribute $attr.

indexable_attrs()

$attrs = $class->indexable_attrs($some_class);

Returns an array ref all all attributes in $some_class which don't have exclude set to true.

import_types()

$class->import_types($other_class);

Imports the deflators, inflators and mappers from another typemap class into the current class.

AUTHOR

Clinton Gormley <drtech@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by Clinton Gormley.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.