| Recommend this page to a friend! |
| Trackbacks (6) | ||||||||||||
| << Previous: PHP compiler performance | >> Next: Neural Networks in PHP |
Documents do not have a predefined schema like relational database tables. Documents can have multiple properties. Documents can also be grouped in collections. The term collection is used from now on distinguish from the tables used by relational databases to store records with a fixed number of fields.
$person = array(
"name" => "Cesar Rodas",
"country" => "Paraguay",
"languages" => array("Spanish", "English", "Guarani"),
);
pecl install mongo
Alternatively, you can
grab PHP MongoDB extension source code
and install it yourself:
phpize
./configure --enable-mongo
make install
$connection = new Mongo();
Connecting to a remote
host with optional custom port:
$connection= new Mongo( "192.168.2.1" );
$connection = new Mongo( "192.168.2.1:65432" );
When
the connection to MongoDB server is established, it is necessary to
select a database to work with. If no database exists already, a new
database is created. Currently there are two ways to do this:Then it is necessary to select a collection to work with, like we would pick a table to work with when using relational databases.
$db = $connection->selectDB('dbname');
$db = $connection->dbname;
$collection = $db->selectCollection('people');
or simply
$collection = $db->people;
$person = array(
'name' => 'Cesar Rodas',
'email' => 'crodas@php.net',
'address' => array(
array(
'country' => 'PY',
'zip' => '2160',
'address1' => 'foo bar'
),
array(
'country' => 'PY',
'zip' => '2161',
'address1' => 'foo bar bar foo'
),
),
'sessions' => 0,
);
$safe_insert = true;
$collection->insert($person, $safe_insert);
$person_identifier = $person['_id'];
As you may have noted, the
$safe_insert parameter is passed to the
insert function. It is meant to make the MongoDB client library wait for
the request to finish, so it is possible to determine whether it
succeeded or not.MongoDB also supports multiple in-place updates, like relational databases can, which means that it can update all documents that match a given criteria. For that it is necessary to pass the set the option multiple to true.
$filter = array('email => 'crodas@php.net');
$new_document = array(
'$inc' => array('sessions' => 1),
'$set' => array(
'address.0.address2' => 'Some foobar street',
),
'$unset' => array('address.1' => 1),
);
$options['multiple'] = false;
$collection->update(
$filter,
$new_document,
$options
);
$filter = array('email' => 'crodas@php.net');
$cursor = $collection->find($filter);
foreach ($cursor as $user) {
var_dump($user);
}
$filter = array('sessions' => array('$gt' => 10));
$cursor = $collection->find($filter);
$filter = array(
'sessions' => array('$exists' => false)
);
$cursor = $collection->find($filter);
$filter = array(
'address.country' => 'PY',
'sessions' => array('$gt' => 10)
);
$cursor = $collection->find($filter);
$total = $cursor->total();
$cursor->limit(20)->skip(40);
foreach($cursor as $user) {
}
$countries = $collection->distinct(
array("address.country")
);
$result = $collection->group(
/* keys to group by */
array("address.country" => True),
/* initial value */
array("sum" => 0),
/* js code to reduce */
"function (obj, prev) { prev.sum += 1; }",
/* Filter condition */
array("session" => array('$gt' => 10))
);
$filter = array('field' => 'foo');
$collection->remove($filter);
Be careful. By default
all documents that match a given criteria will be deleted. If you just
want to delete the first document that matches the criteria, pass true
to the second parameter of the remove function..
$collection->ensureIndex(
array('email' => 1),
array('unique' => true, 'background' => true)
);
The first array parameter
describes all the properties that should be part of the index. It may be
just one property or more properties.
$collection->ensureIndex(
array('address.country' => 1, 'sessions' => 1),
array('background' => true)
);
The
value assigned to each index property defines the index order: 1 is for
descending order and -1 for ascending order.
$filter = array(
'address.country' => 'PY',
);
$cursor = $collection->find($filter)->order(
array('sessions' => -1)
);
$collection->ensureIndex(
array('address.country' => 1, 'sessions' => -1),
array('background' => true)
);

As you may notice, we only need one document to represent both the posts and comments. That is because comments are sub-documents of post documents.
$users = array(
'username' => 'crodas',
'name' => 'Cesar Rodas',
);
$posts = array(
'uri' => '/foo-bar-post',
'author_id' => $users->_id,
'title' => 'Foo bar post',
'summary' => 'This is a summary text',
'body' => 'This is the body',
'comments' => array(
array(
'name' => 'user',
'email' => 'foo@bar.com',
'content' => 'nice post'
)
)
);
$posts = array(
'uri' => '/foo-bar-post',
'author_id' => $users->_id,
'author_name' => 'Cesar Rodas',
'author_username' => 'crodas',
'title' => 'Foo bar post',
'summary' => 'This is a summary text',
'body' => 'This is the body',
'comments' => array(
array(
'name' => 'user',
'email' => 'foo@bar.com',
'comment' => 'nice post'
),
)
);
This means that some
duplicated information may exist, but keep in mind that disk space is
much cheaper than CPU and RAM, and even more important that the time and patience
of your site visitors.Given these optimizations of our data model, lets rewrite some SQL as equivalent queries to MongoDB.
$filter = array(
'author_id' => $author['_id'],
);
$data = array(
'$set' => array(
'author_name' => 'Cesar D. Rodas',
'author_username' => 'cesar',
)
);
$collection->update($filter, $data, array(
'multiple' => true)
);
First, add this index just once:
SELECT * FROM posts
INNER JOIN users ON users.id = posts.user_id
WHERE URL = :url;
SELECT * FROM comments WHERE post_id = $post_id;
$collection->ensureIndex(
array('uri' => 1),
array('unique' => 1, 'background')
);
$collection->find(array('uri' => '<uri>'));
INSERT INTO comments(post_id, name, email, contents)
VALUES(:post_id, :name, :email, :comment);
$comment = array(
'name' => $_POST['name'],
'email' => $_POST['email'],
'comment' => $_POST['comment'],
);
$filter = array(
'uri' => $_POST['uri'],
);
$collection->update($filter, array(
'$push' => array('comments' => $comment))
);
First, add this index just once:
SELECT * FROM posts WHERE id IN (
SELECT DISTINCT post_id FROM comments WHERE email = :email
);
$collection->ensureIndex(
array('comments.email' => 1),
array('background' => 1)
);
$collection->find( array('comments.email' => $email) );
$metadata = array(
"filename" => "path.avi",
"downloads" => 0,
"comment" => "This file is foo bar",
"permissions" => array(
"crodas" => "write",
"everybody" => "read",
)
);
$grid = $db->getGridFS();
$grid->storeFile("/file/to/path.avi", $metadata);
As you see, it is very
simple and easy to understand.Then execute the map-reduce command:
$map = new MongoCode("function () {
var i;
for (i=0; i < this.tags.length; i++) {
/* Emit every tag with a document with {count:1} */
emit(this.tags[i], {count: 1});
}
}");
$reduce = new MongoCode("function (key, values) {
var i, total=0;
for (i=0; i < values.length; i++) {
total = values[i].count;
}
return {count: total}
}");
If MongoDB runs in a sharded environment, the data processing functions will run in parallel on all shards.
$map_reduce = array(
/* create a new collection */
'out' => 'tags_info',
/* return the debug info */
'verbose' => true,
/* process the posts collection */
'mapreduce' => 'posts',
'map' => $map,
'reduce' => $reduce,
);
$information = $db->command($map_reduce);
var_dump($information);

Comments:
3. regex - geert van bommel (2012-02-03 08:07)
did you find how to?... - 3 replies
Read the whole comment and replies
6. a sample - Amir H Fadaee (2011-10-05 20:20)
please let us know about a useful real sample... - 0 replies
Read the whole comment and replies
5. performance - sody sody (2010-03-04 07:20)
MongoDb performance vs MySql/MSsql... - 1 reply
Read the whole comment and replies
2. ActiveRecord wrapper - Jonathan Moss (2010-03-03 19:20)
Take a look at Morph for MongoDB... - 3 replies
Read the whole comment and replies
4. Visual Interfaces - Victor Okech (2010-03-02 17:20)
MongoDB PHPMyAdmin access... - 1 reply
Read the whole comment and replies
1. Opinion on article - Alan H. Lake (2010-03-01 16:54)
Very well written article... - 1 reply
Read the whole comment and replies
6. Desenvolvendo aplicações escaláveis com PHP e MongoDB (2010-05-05 10:47)
Ótimo tutorial no PHP Classes sobre como desenvolver aplicações escaláveis com MongoDB...
5. MongoDB and PHP (2010-04-19 01:38)
Looked for a reliable document oriented database, and after some tests and code, decided to give a try on MongoDB for a small proof of concept that i am working on...
4. Armazenar arquivos com MongoDB (2010-05-07 03:09)
O MongoDB também oferece recursos que vão além das operações de banco de dados...
3. Part1 – Learning & Sharing Series – MongoDB -java (2010-03-30 12:29)
This document is to share some info collected from web and few features i tried out...
2. MongoDB looks Interesting (2010-03-06 13:24)
I might take a look at installing MongoDB on my server...
1. PHPClasses.org Blog: Developing scalable PHP applications using MongoDB (2010-03-01 07:16)
New on the PHPClasses.org blog today there’s a tutorial (written up by Cesar Rodas) about using MongoDB (a NoSQL database) in PHP applications...
| << Previous: PHP compiler performance | >> Next: Neural Networks in PHP |
| Trackbacks (6) | ||||||||||||