Text

MongoDB + PHP driver: running map-reduce on secondaries

If you got here, you already know that by now PHP driver (<= 1.2) for Mongo don’t do queries on secondary using the setSlaveOkay() method.

You can use this quick&dirty hack:

$result = $_mongo->selectCollection(‘$cmd’)->find(array(“group” => array(“ns” => “collectionName”, ‘$key’ => $key, ‘$condition’ => $condition, ‘initial’ => $initial, ‘$reduce’ => $reduce)))->slaveOkay()->limit(1)->getNext();

That should solve your problem.

Text

Quick Snippet: get creation time from id on MongoDB

This can be useful to someone: you can get the creation time from a Mongo ObjectId, simply by looking at the first four bytes of the id.

PHP example:

$creation_date = date(‘Y-m-d H:i:s’, hexdec(substr($id, 0, 8)));

You can also use MongoId::getTimestamp method from Mongo PHP driver, if it’s loaded :-)

Text

symfony + MongoDB (mondonGO) sandbox on Github

I’ve just created and configured a sandbox to who want to play with MongoDB and symfony (1.4) here: https://github.com/dicarsio/symfony-mongo-sandbox

You just need to run the shell script named download-submodules.sh from project folder and you are setup!

This release has already mondoGO Behaviors on it.

Text

MongoDB + Symfony 1.4 with sfMondongoPlugin

As a first post, I’ll show you how easy is to integrate MongoDB (and MondonGO ODM) with Symfony 1.4, with the help of sfMondongoPlugin.

Installing Plugin

Assuming you already have Symfony 1.4 installed, you will need to install the plugin:

$ ./symfony plugin:install -s beta sfMondongoPlugin

Configuring Connection

You need to configure the connection to MongoDB, thru config/databases.yml file:

all:
  mondongo:
    class: sfMondongoDatabase
    param:
      server:   mongodb://localhost:27017
      database: mondongo_database

So, obviously you need to set the right host and database that fits you, but its all you need to do to setup a new connection.

You can setup some options, too like persistence:

all:
  mondongo:
    class: sfMondongoDatabase
    param:
      server:   mongodb://localhost:27017
      database: mondongo_database
      options:
         persist: 1
         connect: 1

 (For more options, you can check the Mongo::__contruct parameters in PHP manual.

Schema YML File

The schema is very similar to Doctrine ORM, and you have extensions too (like the good old Taggable, or Timestampable). However, you use a different parent variable to set them up (as opposite of “actAs:”).

An example:

Winery:
  connection: mondongo
  collection: wineries
  fields:
    name:             { type: string, required: true }
    address:          { type: string, required: false }
    zip:              { type: string, required: false }
    city:             { type: string, required: false }
    state:            { type: string, required: false }
    country_id:       { type: reference_one, required: false }
    email:            { type: string, required: false }
    url:              { type: string, required: false }
    phone:            { type: string, required: false }
    description:      { type: string, required: false }
  references:
    country: { class: Country, field: country_id, type: one }
  extensions:
    - { class: Mondongo\Extension\Extra\Timestampable }
    - { class: Mondongo\Extension\Extra\Sluggable, options: { from_field: name } }

Country:
  connection: mondongo
  collection: countries
  fields:
    name:             string
  extensions:
    - { class: Mondongo\Extension\Extra\Sluggable, options: { from_field: name } }

Update: a note from Pablo Diez, creator of mondonGO: you don’t have to specify the connection and collection parameters. mondonGO will use the first found connection, and underscore_class_name as collection name.

Working with documents

I already talked about setting up the database connection and schema creation so, at last, I’ll show you how to create and retrieve documents.

Saving a document is really easy. You just have to call the class used in schema:

$winery = new Winery();
$winery->name = 'Domaine Barge';
$winery->url = 'http://www.domainebarge.com/";
$winery->save();

It’s pretty common if you used to create objects in doctrine, so I guess you already know that!

Querying mongo can be done by two ways - from the repository or from mondonGO directly:

// from repository
$mondongo = $this->getMondongo();
$winery_repository = $mondongo->getRepository('Winery');
$this->wineries = $winery_repository->find(array(
   'query' => array('slug' => 'domaine-barge'),
   'limit'  => 10
));

// from mondonGO
$mondongo = $this->getMondongo();
$this->wineries = $mondongo->find('Winery', array(
   'query' => array('slug' => 'domaine-barge'),
   'limit'  => 10
));

// and if you want to get all winery records..
$mondongo = $this->getMondongo();
$winery_repository = new WineryRepository($mondongo);
$this->wineries = $winery_repository->find();

So, I guess it’s pretty much what I have to show you. If you want you can dig more into it here and here.

Questions? Suggestions? Drop me a line.