NAME
Meerkat::Tutorial - Getting started with Meerkat
VERSION
version 0.016
TUTORIAL
Prerequisites
If you don't already have MongoDB installed and running, see the installation guide.
Check that you can connect to the test
database from the mongo
shell:
$ mongo test
Creating Your Document Model
A Meerkat document is just a Moose class with the Meerkat::Role::Document role applied. This tutorial uses a simplified version of the My::Model::Person
class used for testing. It has a required name
attribute, and also attributes for likes
and tags
:
package My::Model::Person;
use Moose;
with 'Meerkat::Role::Document';
has name => (
is => 'ro',
isa => 'Str',
required => 1,
);
has likes => (
is => 'ro',
isa => 'Num',
default => 0,
);
has tags => (
is => 'ro',
isa => 'ArrayRef',
default => sub { [] },
);
1;
Meerkat::Role::Document will also add _id
, _collection
and _removed
attributes.
Note that all attributes are read-only. You don't want to modify these directly or you'll be out of sync with the database and bad things will happen. You will update attributes using the update
methods, shown later.
Connecting to the Database
Once the document class is written, using it requires a Meerkat object to manage the connection to the database:
use Meerkat;
my $meerkat = Meerkat->new(
model_namespace => "My::Model",
database_name => "test",
);
By specifying a model_namespace
of "My::Model", the object will return collections for classes underneath that namespace. The example above will connect to the default MongoDB on localhost. If your MongoDB is running on a different host or port, you could pass client_options
which will be passed through to the MongoDB::MongoClient constructor.
Actually working with the document class requires getting a Meerkat::Collection object from the Meerkat object. A Meerkat collection associates a Perl class name with a specific MongoDB collection in the database managed by the Meerkat object.
my $person = $meerkat->collection("Person"); # My::Model::Person
The collection name is derived from the Perl class by replacing "::" with "_". So "My::Model::Person" objects are stored in the "My_Model_Person" collection. In this tutorial example, that collection is in the "test" database on the localhost MongoDB.
Creating New Documents
A Meerkat document needs to know what collection it came from, so the Meerkat::Collection is a factory for constructing objects.
my $obj = $person->create( name => "Larry Wall" );
When the object is created, it is immediately inserted into the database. (If an error occurs, an exception is thrown.)
Don't create objects directly from the document class. Even if you provide a Meerkat::Collection, the documents won't be inserted and things will never get in sync. Always create objects from a Meerkat::Collection.
Updating, Synchronizing and Removing Documents
With Meerkat, objects reflect the state of a document in the database at a moment in time. Therefore, you never change the state of your object directly, because it might no longer reflect the true state of the document in the database. Instead, you issue database commands to modify the document atomically in the database and then Meerkat synchronizes your object with the result.
Conveniently, Meerkat::Role::Document gives your model class some methods to make that easy:
$obj->update_set ( name => "Warry Lall" ); # change a field
$obj->update_inc ( likes => 1 ); # increment a counter
$obj->update_push( tags => qw/hot trendy/ ); # push to an array
If you aren't changing data, but want to update your object's snapshot of the document in the database, call the sync
method:
$obj->sync
And should you need to get rid of a document, the remove
method will take care of it.
$obj->remove
Afterwards, is_removed
will be true and update
and sync
calls will do nothing and return a false value.
Errors
Generally, Meerkat methods return true if they executed successfully and false if they could not.
For example, if a document was removed in the database by another process and an update
or sync
is called, it will return false. (It will flag the object as having been removed from the database, but will not otherwise modify its data.)
Should any major error occur, an exception will get thrown.
Searching the Database
To retrieve a document from the database, the collection provides search methods similar to MongoDB::Collection, but which return objects from your model class.
For single objects, there are the find_id
and find_one
methods:
# find a single object
my $obj1 = $person->find_id( $id );
my $obj2 = $person->find_one( { name => 'John' } );
If you have a MongoDB query for multiple objects, you pass it to find
and get a Meerkat::Cursor object back. It proxies for MongoDB::Cursor but returns objects when iterated.
my $cursor = $person->find( $query_hashref );
while ( my $obj = $cursor->next ) { ... }
Next steps
Try out the example class above using the 'test' database on your machine.
Afterwards, check out the Meerkat::Cookbook for more on working with Meerkat.
AUTHOR
David Golden <dagolden@cpan.org>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2013 by David Golden.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004