Getting started with MongoDB using Perl - insert and simple update
MongoDB is an open-source NoSQL document database. In this article we see the basics: How to insert a document in a MongoDB collection and how to update a document.
Inserting elements
The most simple example is inserting two element in a collection.
examples/mongodb_insert_two_elements.pl
use strict; use warnings; use 5.010; use MongoDB (); use Data::Dumper qw(Dumper); my $client = MongoDB::MongoClient->new(host => 'localhost', port => 27017); my $db = $client->get_database( 'example_' . $$ . '_' . time ); my $people_coll = $db->get_collection('people'); $people_coll->insert_one( { name => 'First', }); $people_coll->insert_one( { name => 'Second', }); my $people = $people_coll->find; while (my $p = $people->next) { print Dumper $p; } $db->drop;
my $client = MongoDB::MongoClient->new(host => 'localhost', port => 27017); connects to the MongoDB server running on the same machine at the default port.
The next call: my $db = $client->get_database( 'example_' . $$ . '_' . time ); returns a database. In order to reduce the chances that we access an already existing database we create the name of the database on the fly using the current process id $$ and the current time in seconds.
Once we have the database object in $db we fetch the collection which is similar to tables in relational databases, with the big difference that we don't need to execute special commands to create it or to set up a schema: my $people_coll = $db->get_collection('people');
The next two calls insert data structures (hash references) in the collection. In the terminology of MongoDB they are called documents:
$people_coll->insert_one( { name => 'First', }); $people_coll->insert_one( { name => 'Second', });
Then we call find to fetch all the documents. It returns an object that can be used to iterate over all the documents returned by find using the next method of the object.
my $people = $people_coll->find; while (my $p = $people->next) { print Dumper $p; }
On every iteration this return a hash reference (stored in $p) that contains the document. We use Data::Dumper to print them out:
$VAR1 = { '_id' => bless( { 'value' => '52861f9602490acc35000000' }, 'MongoDB::OID' ), 'name' => 'First' }; $VAR1 = { '_id' => bless( { 'value' => '52861f9602490acc35000001' }, 'MongoDB::OID' ), 'name' => 'Second' };
In addition to the data we inserted, each document also contains another field called _id that is the unique id of this document, called the ObjectIDd. (but read the specification for more, well, specific details.)
The last statement in this example is $db->drop;. As the name might let you guess, it will drop the database so we won't have lots of example databases hanging around.
Manually dropping a database
If for some reason the database is not dropped at the end of the script (e.g. if there was an exception in the code we can manually drop the database using the mongo command line client:
$ mongo MongoDB shell version: 2.4.6 connecting to: test > show dbs demo 0.078125GB dev_site 0.203125GB example_13930_1384522288 0.203125GB local 0.078125GB > use example_13930_1384522288 switched to db example_13930_1384522288 > db.dropDatabase() { "dropped" : "example_13930_1384522288", "ok" : 1 } > show dbs demo 0.078125GB dev_site 0.203125GB local 0.078125GB > exit bye $
show dbs will list all the databases. (There were 4 in this MongoDB installation)
use example_13930_1384522288 switches to the database.
db.dropDatabase() drops the database and
exit, quits the client.
Dropping the database at the END
Another idea might be to put the database dropping code in an END block:
END { $db->drop if $db; }
That will ensure that the database is dropped even if there was an exception in the code.
The if was added so we won't call drop if for some reason we don't even have a database object.
Update one of the documents
Now that we know how to insert data, let's see an example to update one of the documents. After the second call to insert I added this code:
$people_coll->update( { name => 'Second'}, { '$set' => { phone => '1-123', }, }, );
update gets two hash references. The first one { name => 'Second'} is the selector (what would be a WHERE-clause in SQL). It means, update the document where the "name" field equals to 'Second'.
The second hash reference does the actual update. '$set' is a MongoDB command that tells the database engine to set a value. The { phone => '1-123'} part tells to set the phone field to be '1-123'. Regardless if it existed or not before.
The output now looks like this:
$VAR1 = { 'name' => 'First', '_id' => bless( { 'value' => '52862563527197d436000000' }, 'MongoDB::OID' ) }; $VAR1 = { 'name' => 'Second', '_id' => bless( { 'value' => '52862563527197d436000001' }, 'MongoDB::OID' ), 'phone' => '1-123' };
The ObjectIds has changed because this was a new run. That's not the point of this example.
The interesting part is that the second document now has both a 'name' and a 'phone' field while the first document only has a 'name'.
Comments
Great set of articles on getting started with mongodb and perl! They are concise and helped me get started and gave me a better understanding how to utilize this technology. It would be great if you could post an article on how to join collections.
k, I'm using your website for years now, each and every time that I have something new to me, to do with Perl I come here and you have the answer. I don't think that I would have been as good with Perl than I am now without this website ! So thanks a lot for your work, it helps me a lot of times for at least 5 years now, thanks for the efficiency of your explanation, it's always clear and without useless information ! And thanks for this tutorial with Mongo ! I just started Mongo and this helps me a lot !
Looks like the newest version of the MongoDB module uses insert_one instead of insert: https://perlmaven.com/pod/mongodb#MongoDB::Collection
Great content as per your usual high standards! However, I am having a problem connecting to the mongodb server from my perlscript (or using your script above) and have spent ages trying to figure how to fix. The mongodb server IS running on the 27017 port and I can view my test databases using from the mongo shell or via compass BUT on trying to connect via perl, I am getting the error:
"MongoDB::SelectionError: No readable server available for matching read preference primary. MongoDB server status: Topology type: Single; Member status: localhost:27017 (type: Unknown, error: MongoDB::NetworkError: Could not connect to 'localhost:27017': Bad address )"
The line: my $client = MongoDB::MongoClient->new(host => 'localhost', port => 27017);
does not appear to throw the error, but trying to create or amend a dbase does. Any suggestions solutions most welcome!
Published on 2015-04-27