Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
224 views12 pages

Mango Perl

Download as docx, pdf, or txt
Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1/ 12

y y y y y y

y y

NAME DESCRIPTION TERMINOLOGY PREAMBLE CONNECTING CRUD o Creating Documents o Retrieving Documents o Updating Documents o Deleting Documents MONGO BASICS o Database Commands NEXT STEPS

NAME
MongoDB::Tutorial - Getting started with MongoDB

DESCRIPTION
The tutorial runs through the basic functionality of the MongoDB package. This is a good starting point if you have never used MongoDB before. The tutorial assumes that you are running a Mongo database server locally on the default port. You can download Mongo from http://www.mongodb.org.

TERMINOLOGY
Document-oriented database terms and their relational equivalents: Database Database Collection Table Document Record or row MongoDB::OID Autoincrementing primary key

PREAMBLE

The MongoDB package load MongoDB::Connection, MongoDB::Database, MongoDB::Collection, and MongoDB::Cursor. To use special Mongo data types (see MongoDB::DataTypes), you have to include them separately. So, usually, to use Mongo, you'll start with at least:
use MongoDB; use MongoDB::OID;

CONNECTING
To get started, we have to connect to the database server. Because it's running locally on the default port, we need not pass any parameters to the MongoDB::Connection constructor:
my $conn = MongoDB::Connection->new;

Now we're connected to the database server. Next we need a database to work with, we'll call it "tutorial". You need not do anything special to create the database, Mongo will create it on the fly.
my $db = $conn->tutorial;

The last part of the preliminary setup is to choose a collection. We'll be using the "users" collection to start out.
my $users = $db->users;

Again, there is no need to create the collection in advance, it will be created as needed.

CRUD
Creating Documents
Before you get started with MongoDB, it is important to know that, by default, MongoDB does not return a response from writes (inserts, updates, and deletes). If you would like to know if the insert succeeded or failed, use the safe option. For more information on this, see http://www.mongodb.org/display/DOCS/Last+Error+Commands for details.

Inserting
To add a document to the collection, we use the insert function. It takes a hash which is saved to the collection.
$users->insert({"name" => "Joe", "age" => 52, "likes" => [qw/skiing math ponies/]});

Now there is a user in the collection.

MongoDB::OIDs
When a document is inserted, it is given a _id field if one does not already exist. By default, this field is a MongoDB::OID, 12 bytes that are guaranteed to be unique. The _id field of the inserted document is returned by the insert method.
my $id = $users->insert({"name" => "Bill"});

An efficient way to insert documents is to send many at a time to the database by using batch_insert, which returns an array of the _id fields of the documents inserted.
@ids = $users->batch_insert(\@fifty_users);

Retrieving Documents
Queries
To retrieve documents that were saved to a collection, we can use the find method.
my $all_users = $users->find;

To query for certain criteria, say, all users named Joe, pass the query a hash with the key/value pair you wish to match:
my $some_users = $users->find({"name" => "Joe"});

You can match array elements in your querys; for example, to find all users who like math:
my $geeks = $users->find({"likes" => "math"});

This being Perl, it is important to mention that you can also use regular expressions to search for strings. If you wanted to find all users with the name John and all variations of said name, you could do:
my $john = $users->find({"name" => qr/joh?n/i});

See MongoDB::DataTypes/"Regular Expressions" for more information.

Ranges
As queries are hashes, they use a special syntax to express comparisons, such as "x < 4". To make the query a valid hash, Mongo uses $-prefixed terms. For example, "x < 4" could be expressed by:

my $doc321 = $collection->query({'x' => { '$lt' => 4 }});

Comparison operators can be combined to get a range:


my $doc32 = $collection->query({'x' => { '$gte' => 2, '$lt' => 4 }});

Cursors
query returns a MongoDB::Cursor, which can be iterated over. It lazily loads results from the

database. The following prints all of the users' names:


while (my $doc = $all_users->next) { print $doc->{'name'}."\n"; }

A cursor can also be converted into an array of hash references. For example, to print the "name" field of the first result:
my @arr = $geeks->all; print $arr[0]->{'name'}."\n";

Updating Documents
$-operators

To change a document after it has been saved to the database, you must pass update two arguments. The first is a query argument, identical to the previous section, to identify the document you want to change. The second is an argument that describes the change that you wish to make. The change is described by $-prefixed descriptors. For example, to increment a field, we would write:
$users->update({"_id" => $id}, {'$inc' => {'age' => 1}});

To add an element to an array, we can use $push. So, to add an element to the "likes" array, we write:
$users->update({"_id" => $id}, {'$push' => {'likes' => 'reading'}});

To add a new field or change the type or value of an existing field, we use $set. For example, to change the _id field to a username, we would say:
$users->update({"_id" => $id}, {'$set' => {'_id' => 'joe_schmoe'}});

Options

By default, update operates on one matching document, and does nothing if no document matches the query. There are two options available to change this behavior. Suppose we want to add a "gift" field to everyone whose birthday it is today. One way would be to find every person whose birthday it was and iterate through the user documents, updating each one. However, it would be much faster and easier to update multiple documents at once. We can do this by using an optional third parameter with update:
my $today = DateTime->now; my $tomorrow = DateTime->now->set('day' => $today->day+1); $users->update({"bday" => {'$gte' => $today, '$lte' => $tomorrow}}, {'$set' => {'gift' => $gift}}, {'multiple' => 1});

(This functionality was added in version 1.1.3 of the database and will not work in earlier versions.) Sometimes we may want update to create an element if it does not already exist. This is called an 'upsert' (as it is a combination of an update and an insert). For example, the same code could be used for creating and updating a log document:
$pageviews->update({"url" => "www.example.com"}, {'$inc' => {"views" => 1}}, {'upsert' => 1});

If the pageview counter for www.example.com did not exist yet, it would be created and the "views" field would be set to 1. If it did exist, the "views" field would be incremented.

Deleting Documents
To delete documents, we use the remove method. It takes the same type of hash queries do:
$users->remove({"name" => "Joe"});

Calling remove with no parameters removes all of the objects in a collection. It does not delete the collection, though (in that in that it will still appear if the user lists collections in the database and the indexes will still exist). To remove a collection entirely, call drop:
$users->drop; drop can also be used for whole databases: $db->drop;

MONGO BASICS
Database Commands

There are a large number of useful database commands that can be called directly with $db>run_command. For example, to drop a collection, you can use:
$db->run_command({drop => $collection_name});

"drop" only requires one key/value pair, but for commands that require multiple fields, Mongo expects key/value pairs to be in a certain order. It will not recognize the command if they are not ordered command name first. Thus, if you are running a database command, you should probably use Tie::IxHash instead of a normal hash (normal hashes are not ordered). For example, you can use a database command to create a capped collection like so:
my $cmd = Tie::IxHash->new("create" => "posts", "capped" => boolean::true, "size" => 10240, "max" => 100); $db->run_command($cmd);

This will create a capped collection called "posts" in the current database. It has a maximum size of 10240 bytes and can contain up to 100 documents.

NEXT STEPS
Now that you know the basic syntax used by the Perl driver, you should be able to translate the JavaScript examples in the main MongoDB documentation (http://www.mongodb.org) into Perl. If there's anything else you'd like to see as part of the tutorial or documentation in general, please contact kristina@mongodb.org.

Examples

y y

NAME DATABASE COMMANDS o Distinct o MapReduce UPDATING o Positional Operator

NAME
MongoDB::Examples - Some more advanced examples

DATABASE COMMANDS
Distinct
The distinct command returns all values for a given key in a collection. For example, suppose we had a collection with the following documents (_id value ignored):
{ { { { 'name' 'name' 'name' 'name' => => => => 'a', 'b', 'c', 'd', code code code code => => => => 1 } 1 } 2 } "3" }

If we wanted to see all of values in the "code" field, we could run:


my $result = $db->run_command([ "distinct" => "collection_name", "key" => "code", "query" => {} ]);

Notice that the arguments are in an array, to ensure that their order is preserved. You could also use a Tie::IxHash.
query is an optional argument, which can be used to only run distinct on specific documents.

It takes a hash (or Tie::IxHash or array) in the same form as MongoDB::Collection/"find($query)". Running distinct on the above collection would give you:
{ 'ok' => '1', 'values' => [ 1, 2, "3" ] };

MapReduce
MapReduce is a powerful aggregation tool. (For traditional queries, you should use
MongoDB::Collection::query.)

This example counts the number of occurences of each tag in a collection. Each document contains a "tags" array that contains zero or more strings.
my $map = <<MAP; function() { this.tags.forEach(function(tag) { emit(tag, {count : 1}); }); } MAP my $reduce = <<REDUCE; function(prev, current) { result = {count : 0}; current.forEach(function(item) { result.count += item.count; }); return result; } REDUCE my $cmd = Tie::IxHash->new("mapreduce" => "foo", "map" => $map, "reduce" => $reduce); my $result = $db->run_command($cmd);

See the MongoDB documentation on MapReduce for more information (http://dochub.mongodb.org/core/mapreduce).

UPDATING
Positional Operator
In MongoDB 1.3.4 and later, you can use positional operator, $, to update elements of an array. For instance, suppose you have an array of user information and you want to update a user's name. A sample document in JavaScript:
{ "users" : [ { "name" : "bill", "age" : 60 }, { "name" : "fred", "age" : 29 }, ]

The update:
$coll->update({"users.name" => "fred"}, {'users.$.name' => "george"});

This will update the array so that the element containing "name" => "fred" now has "name"
=> "george".

Tutorial Please go-through this

Introduction
This page is a brief overview of working with the MongoDB Perl driver. For more information about the Perl API, please refer to the online API Documentation for Perl Driver (coming soon).

A Quick Tour
Be sure to add
use MongoDB;

in all of the following code samples.


Making a Connection

To connect to a MongoDB server running locally on the default port, use:


my $conn = MongoDB::Connection->new;

To specify a non-default location, specify host and port:


my $conn = MongoDB::Connection->new("host" => "example.com", "port" => 12345);

To connect to two servers in a master/slave setup, you must specify the left_host and right_host. The example below connects to localhost:27017 and localhost:27018:

my $conn = MongoDB::Connection->new("left_host" => "localhost", "right_host" => "localhost", "right_port" => 27018);

Order doesn't matter, the driver will check which is master for you. If a connection is lost, the driver will figure out the new master.
Authentication (optional)

MongoDB can be run in secure mode, where access to the database requires a username and password. If the database is running in this mode, any client connection must be authenticated before using the database. You can authenticate a connection for a particular database by calling:
$logged_in = $connection->authenticate("db_name", "username", "password");

Getting a Database

Once a connection is established, you can select a database:


my $db = $conn->get_database('foo');

Database names can't have "$"s or "."s in them.


Getting A Collection

Most database interaction will occur at a collection level (inserting and querying). To select a collection, use:
my $coll = $db->get_collection('bar');

Collection names can't have "$"s in them.


Inserting a Document

Once you have the collection object, you can insert documents into the collection. For example, lets make a little document that in JSON would be represented as
{ "name" : "MongoDB", "type" : "database", "count" : 1, "info" : { x : 203, y : 102 } }

To insert this object, we simply create a hash using its fields and use the insert() method.

$coll->insert({name => "MongoDB", type => "database", count => 1, info => {x => 203, y => 102}});

Finding the First Document In A Collection using find_one()

To show that the document we inserted in the previous step is there, we can do a simple
find_one() operation to get the first document in the collection. This method returns a single document (rather than the MongoDB::Cursor that the find() operation returns), and it's useful

for things where there only is one document, or you are only interested in the first. You don't have to deal with the cursor.
use Data::Dumper; my $doc = $coll->find_one(); print Dumper($doc);

This will display:


$VAR1 = { 'info' => { 'y' => 102, 'x' => 203 }, 'count' => 1, '_id' => bless( { 'value' => '4a9700dba5f9107c5cbc9a9c' }, 'MongoDB::OID' ), 'name' => 'MongoDB', 'type' => 'database' };

Getting Results

You can use a cursor to iterate over results. Cursors are lazy: they only query the database when next, has_next, or all is called. Cursors are created automatically by querying the database:
my $cursor = $collection->query; while (my $obj = $cursor->next) { # do stuff } $cursor->next will return undef when it runs out of results.

Fancy Finding

If you don't want to return every document in the collection, you can make some modifications to your cursor before you start iterating:
my $cursor = $collection->query;

# sort by age, ascending $cursor->sort({age => 1}); # skip the first 4 results $cursor->skip(4); # only return 7 results $cursor->limit(7);

Each cursor command returns the cursor itself, so you can chain them all together. The following is equivalent to the code above:
my $cursor = $collection->query->sort({age => 1})->skip(4)->limit(7);

Using Regular Expressions

You use regular expressions in your queries by using the qr/whatever/ construct. Only m, i, s, and x flags will be used by the database. use locale will also be passed to the database. For example, to find people named Jon, John, jon, and john, you could say:
my $cursor = $collection->query({"name" => qr/[Jj]o(h)?n/});

Database Commands

There are a large number of useful database commands that can be called directly with $db>run_command. For these commands, Mongo expects key/value pairs to be in a certain order, and will no recognize the command if they are not. Thus, if you are running a database command, you should probably use Tie::IxHash instead of a normal hash (normal hashes are not ordered).
Creating an Index

Unique and non-unique indexes can be created on collections using ensure_index:


# non-unique index on 'x' $collection->ensure_index({'x' => 'ascending'}) # unique index on 'y' $collection->ensure_index({'y' => 'ascending', 'z' => 'descending'}, 1);

For multi-key indexes, keep in mind that you should use Tie::IxHash to guarantee the keys will be saved in the correct order.

You might also like