MongoDBx-Class
view release on metacpan or search on metacpan
lib/MongoDBx/Class/Tutorial.pod view on Meta::CPAN
Let's take a look at the first way. Suppose we want to cheat and update
all reviews for "The Valley of Fear" with a score of five:
$db->reviews->update({ 'novel.$id' => $novel->_id }, { '$set' => { score => 5 } }, { multiple => 1 }); # updates are by default singular, so we add the 'multiple' option
This is exactly like using L<MongoDB::Collection> directly. If we're updating
a specific document we've already loaded, however, MongoDBx::Class provides
a much more comfortable way. Instead of doing:
$db->novels->update({ _id => $novel->_id }, { ... })
We can do:
$novel->update({ year => 1915 });
This will effectively invoke a '$set' update like this:
$db->novels->update({ _id => $novel->_id }, { '$set' => { year => 1915 } });
But this isn't really the Moose way of doing things, so MongoDBx::Class
gives us yet another way of updating a document:
$novel->set_year(1915); # we can do this because we've added a 'writer' option to the 'year' attribute
$novel->update;
When invoking C<update()> on a document object with no arguments, a "snapshot"
of the document is taken, and the following update is effectively performed:
$db->novels->update({ _id => $novel->_id }, { title => "The Valley of Fear", year => 1915, ... });
When we pass arguments to the C<update()> method (there are two arguments
we can pass, the hash-ref of updates to perform, and the standard options
hash-ref we know from the original C<update()> method in L<MongoDB::Collection>),
MongoDBx::Class simply performs a '$set' update on the passed hash-ref
attributes only. So doing this:
$novel->set_year(1915);
$novel->update({ title => 'The Valley of Fearrrrrr' });
Will only result in the 'title' attribute being updated, not the year
attribute.
Updating embedded documents is similarly easy:
$novel->author->set_first_name('Sir Arthur');
$novel->update;
=head1 REMOVING DOCUMENTS
Removing documents with MongoDBx::Class is very easy. Having the document
object, simply call:
$novel->remove;
Or:
$novel->delete;
And this novel document will be removed from the database. Note, however,
that the delete operation does not cascade, so only the novel document is
deleted. The synopsis and reviews are not deleted, and you have to do so
manually.
You can still use the original C<remove()> method on collections, now mostly
to remove multiple documents:
$db->get_collection('reviews')->remove({ 'novel.$id' => $novel->_id }); # removes are by default multiple
=head1 FAQ
=head2 Can I use more than one database?
Yes, you can use as many databases as you like and use the same document
classes across them:
my $data_db = $conn->get_database('myapp_data');
my $user_db = $conn->get_database('myapp_users');
=head2 Can I define different document classes to different databases?
There currently isn't a way to define individual schemas for different
databases. You can, however, "split" your schema. For example, if your
application has a data DB and a user DB, you can put all the document
classes of the data DB under MyApp::Schema::Data, and all the document
classes of the user DB under MyApp::Schema::User.
=head2 What if I want to use the asynchronous L<AnyMongo> driver instead?
Currently, MongoDBx::Class only supports the official L<MongoDB> driver,
but support for L<AnyMongo> is planned.
=head2 What if I have attributes I don't want to save in the database?
MongoDBx::Class does not provide an option like that yet, but will probably
do so in upcoming versions.
=head2 I'm not getting document objects but just the document hash-refs, what gives?
If, either when searching for documents or creating/updating documents, you are not
receiving expanded document objects back but only the document hash-refs
when searching/updating, or the documents' L<MongoDB::OID>s when inserting,
there might be a few reasons for this:
=over
=item 1. You are not using safe operations: MongoDBx::Class cannot expand
documents when not using safe operations. Either enable the 'safe' option
when inserting/updating, or enable the safe option globally when connecting
using L<MongoDBx::Class>'s C<connect()> method.
=item 2. The document hash-ref does not define the '_class' attribute:
MongoDBx::Class cannot expand document without knowing to which document
class the document belongs. Therefore, documents in the MongoDB database
must have the '_class' attribute.
=item 3. The '_class' attribute is wrong or does not exist: If the document
has the '_class' attribute and you're still not getting document objects
back, then MongoDBx::Class probably can't find the document class. This
might be because the class name is wrong, or the class was not found when
loading MongoDBx::Class. If that is the case, you might wanna take a look
( run in 0.742 second using v1.01-cache-2.11-cpan-39bf76dae61 )