Elastic-Model
view release on metacpan or search on metacpan
lib/Elastic/Model/Role/Model.pm view on Meta::CPAN
package Elastic::Model::Role::Model;
$Elastic::Model::Role::Model::VERSION = '0.52';
use Moose::Role;
use Carp;
use Elastic::Model::Types qw(ES);
use Search::Elasticsearch 1.20 ();
use Class::Load qw(load_class);
use Moose::Util qw(does_role);
use MooseX::Types::Moose qw(:all);
use Elastic::Model::UID();
use Elastic::Model::Deleted();
use Scalar::Util qw(blessed refaddr weaken);
use List::MoreUtils qw(uniq);
use JSON();
our $JSON = JSON->new->canonical->utf8;
use namespace::autoclean;
my @wrapped_classes = qw(
domain namespace store view scope
results cached_results scrolled_results result bulk
);
#===================================
sub BUILD {
#===================================
my $self = shift;
my $es = $self->es;
if ( $es->isa('Search::Elasticsearch::Client::0_90::Direct') ) {
$self->_set_result_class(
$self->_wrap_class('Elastic::Model::0_90::Result') );
$self->_set_store_class(
$self->_wrap_class('Elastic::Model::0_90::Store') );
}
$self->doc_class_wrappers;
return $self;
}
for my $class (@wrapped_classes) {
#===================================
has "${class}_class" => (
#===================================
isa => Str,
is => 'ro',
lazy => 1,
writer => "_set_${class}_class",
default => sub { shift->wrap_class($class) }
);
}
#===================================
has 'typemap' => (
#===================================
is => 'ro',
isa => Str,
default => sub { shift->wrap_class('typemap') }
);
#===================================
has [ 'deflators', 'inflators' ] => (
#===================================
isa => HashRef,
is => 'ro',
default => sub { {} }
);
#===================================
has 'store' => (
#===================================
does => 'Elastic::Model::Role::Store',
is => 'ro',
lazy => 1,
lib/Elastic/Model/Role/Model.pm view on Meta::CPAN
}
\%domains;
}
#===================================
sub namespace_for_domain {
#===================================
my ( $self, $domain ) = @_;
my $ns;
$ns = $self->_get_domain_namespace($domain) and return $ns;
$self->clear_domain_namespace;
$self->_get_domain_namespace($domain)
or croak "No namespace found for domain ($domain). ";
}
#===================================
sub all_live_indices {
#===================================
my $self = shift;
return map { $_->all_live_indices } values %{ $self->namespaces };
}
#===================================
sub wrap_doc_class {
#===================================
my $self = shift;
my $class = shift;
load_class($class);
croak "Class ($class) does not do Elastic::Model::Role::Doc. "
. "Please add : use Elastic::Doc;\n\n"
unless Moose::Util::does_role( $class, 'Elastic::Model::Role::Doc' );
$self->_wrap_class($class);
}
#===================================
sub wrap_class {
#===================================
my $self = shift;
my $name = shift || '';
my $class = $self->meta->get_class($name)
or croak "Unknown class for ($name)";
$self->_wrap_class($class);
}
#===================================
sub _wrap_class {
#===================================
my $self = shift;
my $class = shift;
load_class($class);
my $meta
= Moose::Meta::Class->create(
Class::MOP::class_of($self)->wrapped_class_name($class),
superclasses => [$class] );
weaken( my $weak_model = $self );
$meta->add_method( model => sub {$weak_model} );
$meta->add_method( original_class => sub {$class} );
$meta->make_immutable;
return $meta->name;
}
#===================================
sub domain {
#===================================
my $self = shift;
my $name = shift or croak "No domain name passed to domain()";
my $domain;
$domain = $self->_get_domain($name) and return $domain;
my $ns = $self->namespace_for_domain($name)
or croak "Unknown domain name ($name)";
$domain = $self->domain_class->new(
name => $name,
namespace => $ns
);
return $self->_cache_domain( $name => $domain );
}
#===================================
sub view { shift->view_class->new(@_) }
#===================================
#===================================
sub new_scope {
#===================================
my $self = shift;
my @args
= $self->has_current_scope ? ( parent => $self->current_scope ) : ();
$self->current_scope( $self->scope_class->new(@args) );
}
#===================================
sub detach_scope {
#===================================
my ( $self, $scope ) = @_;
my $current = $self->current_scope;
return unless $current && refaddr($current) eq refaddr($scope);
my $parent = $scope->parent;
return $self->clear_current_scope unless $parent;
$self->current_scope($parent);
}
#===================================
sub get_doc {
#===================================
my ( $self, %args ) = @_;
my $uid = $args{uid}
or croak "No UID passed to get_doc()";
my $ns = $self->namespace_for_domain( $uid->index );
my $scope = $self->current_scope;
my $source = $args{source};
lib/Elastic/Model/Role/Model.pm view on Meta::CPAN
=head1 COMMONLY USED METHODS
=head2 new()
Usually, the only parameter that you need to pass to C<new()> is C<es>,
which contains your L<Search::Elasticsearch> connection.
$es = Search::Elasticsearch->new( nodes => 'es1.domain.com:9200' );
$model = MyApp->new( es => $es );
If the C<es> parameter is omitted, then it will default to a L<Search::Elasticsearch>
connection to C<localhost:9200>.
$model = MyApp->new(); # localhost:9200
=head2 namespace()
$namespace = $model->namespace($name);
Returns the L<Elastic::Model::Namespace> instance corresponding to
C<$name>. The namespace must have been configured via
L<Elastic::Model/has_namespace>.
Use a C<$namespace> to create, delete and update
L<indices|Elastic::Manual::Terminology/Index> and
L<index aliases|Elastic::Manual::Terminology/Alias>.
=head2 domain()
$domain = $model->domain($name);
Returns an L<Elastic::Model::Domain> instance where C<$name> is the name
of an L<index|Elastic::Manual::Terminology/Index> or
L<index alias|Elastic::Manual::Terminology/Alias> (which points at a single
index) and is known to one of the L</namespaces>.
Use a C<$domain> to create, retrieve, update or delete individual
objects/documents.
=head2 view()
$view = $model->view(%args);
Creates a new L<Elastic::Model::View> instance. Any args are passed on to
L<Elastic::Model::View/"new()">.
Use a C<$view> to query your documents. Views can be multi-domain and
multi-type.
=head2 new_scope()
$scope = $model->new_scope();
Creates a new L<Elastic::Model::Scope> instance (in-memory cache). If there is
an existing scope, then the new scope inherits from the existing scope.
$scope = $model->new_scope(); # scope_1
$scope = $model->new_scope(); # scope_2, inherits from scope_1
undef $scope; # scope_2 and scope_1 are destroyed
Scopes are optional unless you have attributes which are weakened.
See L<Elastic::Model::Scoping> and L<Elastic::Model::Scope> to read more about
how scopes work.
=head1 OTHER METHODS AND ATTRIBUTES
These methods and attributes, while public, are usually used only by internal
modules. They are documented here for completeness.
=head2 CRUD
=head3 get_doc()
Normally, you want to use L<Elastic::Model::Domain/"get()"> rather than this
method.
$doc = $model->get_doc(uid => $uid);
$doc = $model->get_doc(uid => $uid, ignore => 404, ...);
C<get_doc()> tries to retrieve the object corresponding to the
L<$uid|Elastic::Model::UID>, first from the L</current_scope()> (if there is one)
or from any of its parents. Failing that, it tries to retrieve the doc
from the L</store>. If it finds the doc, then
it stores it in the current scope (again, if there is one), otherwise it
throws an error.
C<get_doc()> also accepts an optional C<$source> parameter which is
used internally for inflating search results.
See L<Elastic::Model::Scope> for a more detailed explanation.
Any other args are passed on to L<Elastic::Model::Store/get_doc()>.
=head3 get_doc_source()
$doc = $model->get_doc_source(uid => $uid);
$doc = $model->get_doc_source(uid => $uid, ignore => 404, ...);
Calls L<Elastic::Model::Store/"get_doc()"> and returns the raw source hashref
as stored in Elasticsearch for the doc with the corresponding
L<$uid|Elastic::Model::UID>. Throws an error if it doesn't exist.
Any other args are passed on to L<Elastic::Model::Store/get_doc()>.
=head3 doc_exists()
$bool = $model->doc_exists( uid => $uid, %args );
Calls L<Elastic::Model::Role::Store/doc_exists()> to check whether the doc
exists.
=head3 save_doc()
Normally, you want to use L<Elastic::Model::Role::Doc/"save()"> rather than this
method.
$doc = $model->save_doc(doc => $doc, %args);
Saves C<$doc> to Elasticsearch by calling
L<Elastic::Model::Store/"index_doc()"> (if the C<$doc> was originally loaded
from Elasticsearch), or L<Elastic::Model::Store/"create_doc()">, which
( run in 1.255 second using v1.01-cache-2.11-cpan-39bf76dae61 )