<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Inside DealTakerdb » Inside DealTaker</title>
	<atom:link href="http://www.dealtaker.com/our-blog/tag/db/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dealtaker.com/our-blog</link>
	<description>Just another DealTaker.com site</description>
	<lastBuildDate>Tue, 07 Feb 2012 17:39:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>PHP &amp; MongoDB Sitting in a Tree: Part 2</title>
		<link>http://www.dealtaker.com/our-blog/2010/06/22/php-mongodb-sitting-in-a-tree-part-2/</link>
		<comments>http://www.dealtaker.com/our-blog/2010/06/22/php-mongodb-sitting-in-a-tree-part-2/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 08:41:32 +0000</pubDate>
		<dc:creator>ellisgl</dc:creator>
				<category><![CDATA[DealTaker.com Updates]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[Joins]]></category>
		<category><![CDATA[mongo]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Relational]]></category>
		<category><![CDATA[Relations]]></category>
		<category><![CDATA[Schema-less]]></category>
		<category><![CDATA[schemaless]]></category>

		<guid isPermaLink="false">http://www.dealtaker.com/blog/?p=2387</guid>
		<description><![CDATA[In part II of this tutorial series, I&#8217;ll cover securing your MongoDB install and go over &#8220;Relations&#8221;. Before we start, if you have not, read part 1 first. Security So to make good on my promise, let&#8217;s get our MongoDB a little be more secure than what it is today. (*Note: At the time of [...]]]></description>
			<content:encoded><![CDATA[<p>In part II of this tutorial series, I&#8217;ll cover securing your MongoDB install and go over &#8220;Relations&#8221;. Before we start, if you have not, <a href="http://www.dealtaker.com/blog/2010/05/12/php-mongodb-sitting-in-a-tree-part-1/">read part 1</a> first.<br />
<span id="more-2387"></span></p>
<p><strong>Security</strong><br />
So to make good on my promise, let&#8217;s get our MongoDB a little be more secure than what it is today. (*Note: At the time of this writting, MongoDB only supports a simplistic security method, username and password. No encryption, no login server integration, ect.)</p>
<p>First open up your shell/command line and bring up the MongoDB Client. In *NIX, execute &#8220;./mongo&#8221; or Windows, &#8220;mongo&#8221;. Of course you might need to navigate to the location where MongoDB was install and execute it from the &#8220;bin&#8221; path. In my setup I have to execute it from &#8220;C:wampbinmongomongodb-win32-x86_64-1.4.1bin&#8221;.</p>
<p>Now that you have the client up enter in the following commands:</p>
<p>[bash]<br />
use admin<br />
db.addUser(&#8220;admin&#8221;, &#8220;admin_password&#8221;)<br />
db.auth(&#8220;admin&#8221;, &#8220;admin_password&#8221;)<br />
[/bash]</p>
<p>What we have done here is created a DB named &#8220;admin&#8221;, added a user to that DB named &#8220;admin&#8221; with the password of &#8220;admin_password&#8221; (I wouldn&#8217;t use &#8220;admin_password&#8221; for my admin password if I were you), then we authenticated our newly created user. If you don&#8217;t authenticate after adding the user, you won&#8217;t be able to perform any actions. OK, now that we have that taken care of, let get on with &#8220;relations&#8221;.</p>
<p><strong>Having relations</strong><br />
<img src="http://yuml.me/diagram/class/%5Buser|PK%20user_id:uint:nn:ai;username:varchar%2824%29:nn;password:char%2832%29:nn;email:varchar%28255%29],[user_profile|PK%20user_id:uint:nn;aim:varchar%2824%29;yahoo:varchar%2824%29;icq:uint;likes:text;dislikes:text;|FK:FK_user_profile_user_user_id],[user]1-1..*[user_profile]" alt="" width="489" height="141" /><br />
In MySQL, you might have laid out some tables using foreign keys to create <abbr title="one to one">1:1</abbr>, <abbr title="one to many">1:N</abbr>&gt; and <abbr title="many to many">N:N</abbr> relationships between them. So lets take simple 1:1 relationship table layout from MySQL, say &#8220;user&#8221; and &#8220;user_profile&#8221;, which the &#8220;user_profile&#8221; table will have primary key of &#8220;user_id&#8221;, which will be used also as a foreign key to create the relationship.</p>
<p><em>MySQL</em></p>
<p>[php]<br />
&lt;?php<br />
// Connect to MySQL<br />
$host = &#8216;localhost&#8217;;<br />
$user = &#8216;root&#8217;;<br />
$pass = &#8220;&#8221;;<br />
$db   = &#8216;testdb&#8217;;<br />
$link = mysql_connect($host, $user, $pass, 1) or die(&#8220;Could not connect to: {$host}. Check your settings and try again.&#8221;);</p>
<p>// Drop DB if exsists first<br />
$sql  = sprintf(&#8216;SET FOREIGN_KEY_CHECKS = 0;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;DROP DATABASE IF EXISTS `&#8217;.$db.&#8217;`;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the DB<br />
$sql  = sprintf(&#8216;CREATE DATABASE `&#8217;.$db.&#8217;`;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Select the DB<br />
mysql_select_db($db, $link);</p>
<p>// Create the &#8220;user&#8221; table<br />
$sql  = sprintf(&#8216;CREATE TABLE `user`&#8217;.&#8221;n&#8221;.<br />
&#8216;    (`user_id`  INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `username` VARCHAR (24)NOT NULL,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `password` CHAR(32) NOT NULL,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `email`    VARCHAR(255)&#8217;.&#8221;n&#8221;.<br />
&#8216;    ) TYPE=innodb;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the &#8220;user_profile&#8221; table<br />
$sql  = sprintf(&#8216;CREATE TABLE `user_profile`&#8217;.&#8221;n&#8221;.<br />
&#8216;    (`user_id`  INT UNSIGNED NOT NULL PRIMARY KEY,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `aim`      VARCHAR(24),&#8217;.&#8221;n&#8221;.<br />
&#8216;     `yahoo`    VARCHAR(24),&#8217;.&#8221;n&#8221;.<br />
&#8216;     `icq`      INT UNSIGNED,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `likes`    TEXT,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `dislikes` TEXT&#8217;.&#8221;n&#8221;.<br />
&#8216;    ) TYPE=innodb;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the Foreign Key<br />
$sql  = sprintf(&#8216;ALTER TABLE `user_profile`&#8217;.&#8221;n&#8221;.<br />
&#8216;ADD CONSTRAINT `FK_user_profile_user_user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;FOREIGN KEY (`user_id`)&#8217;.&#8221;n&#8221;.<br />
&#8216;REFERENCES `user` (`user_id`);&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);<br />
[/php]</p>
<p>So now we have created a relationship between two tables in MySQL, lets insert a user.<br />
<em>MySQL</em></p>
<p>[php]<br />
// Insert a user<br />
$user = &#8216;jsmith&#8217;;<br />
$pass = &#8217;5f4dcc3b5aa765d61d8327deb882cf99&#8242;;<br />
$eml  = &#8216;jsmith@example.com&#8217;;</p>
<p>$sql  = sprintf(&#8216;INSERT INTO `user`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `username` = &#8216;%s&#8217;,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `password` = &#8216;%s&#8217;,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `email`    = &#8216;%s&#8217;;',<br />
mysql_real_escape_string($user),<br />
mysql_real_escape_string($pass),<br />
mysql_real_escape_string($eml));</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Get the ID of last insert<br />
$id = mysql_insert_id($link);<br />
[/php]</p>
<p>Now that we have a user, let&#8217;s insert the user&#8217;s profile data.<br />
<em>MySQL</em></p>
<p>[php]<br />
// Add a profile for the last inserted user<br />
$aim  = &#8216;MrGoodGuy&#8217;;<br />
$like = &#8216;Ice cream, Pizza and puppies&#8217;;<br />
$dis  = &#8216;Oil spills&#8217;;<br />
$sql  = sprintf(&#8216;INSERT INTO `user_profile`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `user_id`  = %u,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `aim`      = &#8216;%s&#8217;,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `likes`    = &#8216;%s&#8217;,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `dislikes` = &#8216;%s&#8217;;',<br />
$id,<br />
mysql_real_escape_string($aim),<br />
mysql_real_escape_string($like),<br />
mysql_real_escape_string($dis));</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);<br />
[/php]</p>
<p>Now that we have some data in the profile table that relates to the first entry of the user, lets query both tables with an &#8220;INNER JOIN&#8221;.<br />
<em>MySQL</em></p>
<p>[php]<br />
// Query both the &#8220;user&#8221; and &#8220;user_profile&#8221; tables with an &#8220;INNER JOIN&#8221;<br />
$sql  = sprintf(&#8216;SELECT *&#8217;.&#8221;n&#8221;.<br />
&#8216;FROM   `user` `u`&#8217;.&#8221;n&#8221;.<br />
&#8216;    INNER JOIN `user_profile` `p`&#8217;.&#8221;n&#8221;.<br />
&#8216;        ON `p`.`user_id` = `u`.`user_id`;&#8217;);</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);<br />
$cnt  = mysql_num_rows($qry);</p>
<p>echo &#8216;All rows:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}while(&#8211;$cnt &gt; 0);<br />
}<br />
[/php]</p>
<p>Enough of the MySQL example, we will be using document embedding to do the same thing in MongoDB.<br />
<em>MongoDB</em></p>
<p>[php]<br />
&lt;?php<br />
// Connect to MongoDB<br />
$user = &#8216;admin&#8217;;<br />
$pass = &#8216;admin_password&#8217;;</p>
<p>try<br />
{<br />
$link = new Mongo();<br />
$db   = $link-&gt;admin;</p>
<p>$db-&gt;authenticate($user, $pass);<br />
}<br />
catch(MongoConnectionException $e)<br />
{<br />
die(&#8216;Could not connect. Check to make sure MongoDB is running.&#8217;);<br />
}</p>
<p>// Create and use the DB<br />
$db   = $link-&gt;testdb;</p>
<p>// Drop DB if exsists first<br />
$db-&gt;drop();</p>
<p>// Create and use the DB<br />
$db   = $link-&gt;testdb;</p>
<p>// Create the &#8220;user&#8221; colection<br />
$col  = $db-&gt;user;</p>
<p>// Insert a new document<br />
$doc  = array(&#8216;username&#8217; =&gt; &#8216;jsmith&#8217;, &#8216;password&#8217; =&gt; &#8216; 5f4dcc3b5aa765d61d8327deb882cf99&#8242;, &#8216;email&#8217; =&gt; &#8216;jsmith@example.com&#8217;,<br />
&#8216;profile&#8217;  =&gt; array(&#8216;aim&#8217; =&gt; &#8216;MrGoodGuy&#8217;, &#8216;likes&#8217; =&gt; &#8216;Ice cream, Pizza and puppies&#8217;, &#8216;dislikes&#8217; =&gt; &#8216;Oil spills&#8217;));</p>
<p>$col-&gt;insert($doc, true);</p>
<p>// Get the ID of last insert<br />
$id   = $doc['_id'];</p>
<p>// Get all documents<br />
$res = $col-&gt;find();</p>
<p>echo &#8216;All documents:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>&#8220;Wow, pretty simple!&#8221; is what I&#8217;m thinking you are saying to your self. With MongoDB, instead of having to create two tables, the <abbr title="Foreign Key">FK</abbr>,  insert a record, get the id, and do another insert. We create  the collection and just insert our data with a multidimensional associative array.</p>
<p><img src="http://yuml.me/diagram/class/%5Buser|PK%20user_id:uint:nn:ai;username:varchar%2824%29:nn;password:char%2832%29:nn;email:varchar%28255%29],[user_profile|PK%20user_id:uint:nn;aim:varchar%2824%29;yahoo:varchar%2824%29;icq:uint;likes:text;dislikes:text;|FK:FK_user_profile_user_user_id],[user_likes|PK%20user_likes_id:uint:nn:ai;user_id:id:uint:nn;likes:varchar%28255%29%27|FK:FK_user_likes_user_user_id],[user]1-1..*[user_profile],[user]1-.-1..*[user_likes]" alt="" width="456" height="318" /><br />
1:1 relationships are easy, but what about 1:N relationships? Let get back into MySQL mode.<br />
<em>MySQL</em></p>
<p>[php]<br />
// Delete the &#8220;likes&#8221; and &#8220;dislikes&#8221; columns<br />
$sql  = sprintf(&#8216;ALTER TABLE `user_profile`&#8217;.&#8221;n&#8221;.<br />
&#8216;DROP COLUMN `dislikes`,&#8217;.&#8221;n&#8221;.<br />
&#8216;DROP COLUMN `likes`;&#8217;);</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the &#8220;user_likes&#8221; table<br />
$sql  = sprintf(&#8216;CREATE TABLE `user_likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;    (`user_likes_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `user_id`       INT UNSIGNED NOT NULL,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `likes`         VARCHAR(255) NOT NULL&#8217;.&#8221;n&#8221;.<br />
&#8216;    ) TYPE=innodb;&#8217;);</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the Foreign Key<br />
$sql  = sprintf(&#8216;ALTER TABLE `user_likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;ADD CONSTRAINT `FK_user_likes_user_user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;FOREIGN KEY (`user_id`)&#8217;.&#8221;n&#8221;.<br />
&#8216;REFERENCES `user` (`user_id`);&#8217;);</p>
<p>// Create the &#8220;user_dislikes&#8221; table<br />
$sql  = sprintf(&#8216;CREATE TABLE `user_dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;    (`user_dislikes_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `user_id`          INT UNSIGNED NOT NULL,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `dislikes`         VARCHAR(255) NOT NULL&#8217;.&#8221;n&#8221;.<br />
&#8216;    ) TYPE=innodb;&#8217;);</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the Foreign Key<br />
$sql  = sprintf(&#8216;ALTER TABLE `user_dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;ADD CONSTRAINT `FK_user_likes_user_user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;FOREIGN KEY (`user_id`)&#8217;.&#8221;n&#8221;.<br />
&#8216;REFERENCES `user` (`user_id`);&#8217;);</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Insert some &#8220;likes&#8221; and &#8220;dislikes&#8221;<br />
$like = array(&#8216;Ice cream&#8217;, &#8216;Pizza&#8217;, &#8216;Puppies&#8217;);</p>
<p>foreach($like as $val)<br />
{<br />
$sql = sprintf(&#8216;INSERT INTO `user_likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `user_id` = %u,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `likes`   = &#8216;%s&#8217;;',<br />
$id,<br />
mysql_real_escape_string($val));</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);<br />
}</p>
<p>$dis  = array(&#8216;Oil spills&#8217;);</p>
<p>foreach($dis as $val)<br />
{<br />
$sql = sprintf(&#8216;INSERT INTO `user_dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `user_id` = %u,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `dislikes`   = &#8216;%s&#8217;;',<br />
$id,<br />
mysql_real_escape_string($val));</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);<br />
}</p>
<p>// Query the &#8220;user&#8221; table and pull in the &#8220;likes&#8221; and &#8220;dislikes&#8221; data.<br />
$sql  = sprintf(&#8216;SELECT `u`.*,&#8217;.&#8221;n&#8221;.<br />
&#8216;       GROUP_CONCAT(DISTINCT `l`.`likes` SEPARATOR &#8216;, &#8216;) AS `likes`,&#8217;.&#8221;n&#8221;.<br />
&#8216;       GROUP_CONCAT(DISTINCT `d`.`dislikes` SEPARATOR &#8216;, &#8216;) AS `dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;FROM  `user` `u`&#8217;.&#8221;n&#8221;.<br />
&#8216;    INNER JOIN `user_likes` `l`&#8217;.&#8221;n&#8221;.<br />
&#8216;        ON `l`.`user_id` = `u`.`user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;    INNER JOIN `user_dislikes` `d`&#8217;.&#8221;n&#8221;.<br />
&#8216;        ON `d`.`user_id` = `u`.`user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;WHERE `u`.`user_id` = %u;&#8217;,<br />
$id);</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);<br />
$cnt  = mysql_num_rows($qry);</p>
<p>echo &#8216;All rows:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}while(&#8211;$cnt &gt; 0);<br />
}<br />
[/php]</p>
<p>Boy is that a lot of work and I cheated with &#8220;group_concat&#8221; function. Let do this with MongoDB.<br />
<em>MongoDB</em></p>
<p>[php]<br />
// Create a &#8220;1:N&#8221; for &#8220;likes&#8221; and &#8220;dislikes&#8221; in the &#8220;profile&#8221; element<br />
$col-&gt;update(array(&#8216;_id&#8217; =&gt; $id), array(&#8216;$set&#8217; =&gt; array(&#8216;profiles&#8217; =&gt; array(&#8216;likes&#8217;    =&gt; array(&#8216;Ice cream&#8217;, &#8216;Pizza&#8217;, &#8216;Puppies&#8217;),<br />
&#8216;dislikes&#8217; =&gt; array(&#8216;Oil spills&#8217;)))));</p>
<p>echo &#8216;All documents:&lt;br/&gt;&#8217;;</p>
<p>// Get all documents<br />
$res = $col-&gt;find();</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>Since MongoDB is schema-less, we can update how we store the &#8220;likes&#8221; and &#8220;dislikes&#8221; and it comes back to us as an array that we could iterate through. So what&#8217;s next?</p>
<p><img src="http://yuml.me/diagram/class/%5Buser|PK%20user_id:uint:nn:ai;username:varchar%2824%29:nn;password:char%2832%29:nn;email:varchar%28255%29],[user_profile|PK%20user_id:uint:nn;aim:varchar%2824%29;yahoo:varchar%2824%29;icq:uint;likes:text;dislikes:text;|FK:FK_user_profile_user_user_id],[user_likes|PK%20user_id:uint:nn;PK%20user_likes_id:uint:nn;|FK:FK_user_likes_user_user_id;FK:FK_user_likes_likes_likes_id],[user_dislikes|PK%20user_id:uint:nn;PK%20dislikes_id:uint:nn;|FK:FK_user_dislikes_user_user_id;FK:FK_user_dislikes_dislikes_dislikes_id],[likes|PK%20likes_id:uint:nn:ai;likes:varchar%28255%29;],[dislikes|PK%20dislikes_id:uint:nn:ai;dislikes:varchar%28255%29;],[user]1-1..*[user_profile],[user]1-1..*[user_likes],[user]1-1..*[user_dislikes],[likes]1-1..*[user_likes],[dislikes]1-1..*[user_dislikes]" alt="" width="496" height="212" /><br />
N:N relationships. Oh boy are those the ultimate in a relational model. Once again, I&#8217;ll how we do this in MySQL.<br />
<em>MySQL</em></p>
<p>[php]<br />
// Drop &#8220;user_likes&#8221; table if exsists first<br />
$sql  = sprintf(&#8216;SET FOREIGN_KEY_CHECKS = 0;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;DROP TABLE IF EXISTS `user_likes`;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Drop &#8220;dislikes&#8221; table if exsists first<br />
$sql  = sprintf(&#8216;SET FOREIGN_KEY_CHECKS = 0;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;DROP TABLE IF EXISTS `user_dislikes`;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the &#8220;likes&#8221; table<br />
$sql  = sprintf(&#8216;CREATE TABLE `likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;    (`likes_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `likes`    VARCHAR (255) NOT NULL&#8217;.&#8221;n&#8221;.<br />
&#8216;    ) TYPE=innodb;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the &#8220;like&#8221; joins table<br />
$sql  = sprintf(&#8216;CREATE TABLE `user_likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;    (`user_id`  INT UNSIGNED NOT NULL,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `likes_id` INT UNSIGNED NOT NULL,&#8217;.&#8221;n&#8221;.<br />
&#8216;     PRIMARY KEY (`user_id`, `likes_id`)&#8217;.&#8221;n&#8221;.<br />
&#8216;    ) TYPE=innodb;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create Foriegn Keys<br />
$sql  = sprintf(&#8216;ALTER TABLE `user_likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;ADD CONSTRAINT `FK_user_likes_user_user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`),&#8217;.&#8221;n&#8221;.<br />
&#8216;ADD CONSTRAINT `FK_user_likes_likes_likes_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;FOREIGN KEY (`likes_id`) REFERENCES `likes` (`likes_id`);&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Insert some &#8220;likes&#8221;<br />
$sql  = sprintf(&#8216;INSERT INTO `likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `likes` = &#8216;%s&#8217;;',<br />
mysql_real_escape_string(&#8216;Ice Cream&#8217;));</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;INSERT INTO `%s`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `likes` = &#8216;%s&#8217;;',<br />
mysql_real_escape_string(&#8216;likes&#8217;),<br />
mysql_real_escape_string(&#8216;Pizza&#8217;)<br />
);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;INSERT INTO `%s`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `likes` = &#8216;%s&#8217;;',<br />
mysql_real_escape_string(&#8216;likes&#8217;),<br />
mysql_real_escape_string(&#8216;Puppies&#8217;)<br />
);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;INSERT INTO `likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `likes` = &#8216;%s&#8217;;',<br />
mysql_real_escape_string(&#8216;Kittens&#8217;));</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create some &#8220;likes&#8221; relations (Cheating &#8211; since I already know the id&#8217;s)<br />
$sql  = sprintf(&#8216;INSERT INTO `user_likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `user_id`  = %u,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `likes_id` = %u;&#8217;,<br />
1,<br />
1);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;INSERT INTO `user_likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `user_id`  = %u,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `likes_id` = %u;&#8217;,<br />
1,<br />
2);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;INSERT INTO `user_likes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `user_id`  = %u,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `likes_id` = %u;&#8217;,<br />
1,<br />
3);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the &#8220;dislikes&#8221; table<br />
$sql  = sprintf(&#8216;CREATE TABLE `dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;    (`dislikes_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `dislikes`    VARCHAR (255) NOT NULL&#8217;.&#8221;n&#8221;.<br />
&#8216;    ) TYPE=innodb;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create the &#8220;dislike&#8221; joins table<br />
$sql  = sprintf(&#8216;CREATE TABLE `user_dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;    (`user_id`     INT UNSIGNED NOT NULL,&#8217;.&#8221;n&#8221;.<br />
&#8216;     `dislikes_id` INT UNSIGNED NOT NULL,&#8217;.&#8221;n&#8221;.<br />
&#8216;     PRIMARY KEY (`user_id`, `dislikes_id`)&#8217;.&#8221;n&#8221;.<br />
&#8216;    ) TYPE=innodb;&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create Foriegn Keys<br />
$sql  = sprintf(&#8216;ALTER TABLE `user_dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;ADD CONSTRAINT `FK_user_dislikes_user_user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`),&#8217;.&#8221;n&#8221;.<br />
&#8216;ADD CONSTRAINT `FK_user_dislikes_likes_likes_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;FOREIGN KEY (`dislikes_id`) REFERENCES `dislikes` (`dislikes_id`);&#8217;);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Insert some &#8220;dislikes&#8221;<br />
$sql  = sprintf(&#8216;INSERT INTO `dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `dislikes` = &#8216;%s&#8217;;',<br />
mysql_real_escape_string(&#8216;Oil Spills&#8217;));</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>$sql  = sprintf(&#8216;INSERT INTO `dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `dislikes` = &#8216;%s&#8217;;',<br />
mysql_real_escape_string(&#8216;Screaming Babies&#8217;));</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Create some &#8220;dislikes&#8221; relations<br />
$sql  = sprintf(&#8216;INSERT INTO `user_dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;SET    `user_id`  = %u,&#8217;.&#8221;n&#8221;.<br />
&#8216;       `dislikes_id` = %u;&#8217;,<br />
1,<br />
1);</p>
<p>mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);</p>
<p>// Query &#8220;USER&#8221; and join with &#8220;likes&#8221; and &#8220;dislikes&#8221;<br />
$sql  = sprintf(&#8216;SELECT `u`.*,&#8217;.&#8221;n&#8221;.<br />
&#8216;       GROUP_CONCAT(DISTINCT `l`.`likes` SEPARATOR &#8216;, &#8216;) AS `likes`,&#8217;.&#8221;n&#8221;.<br />
&#8216;       GROUP_CONCAT(DISTINCT `d`.`dislikes` SEPARATOR &#8216;, &#8216;) AS `dislikes`&#8217;.&#8221;n&#8221;.<br />
&#8216;FROM  `user` `u`&#8217;.&#8221;n&#8221;.<br />
&#8216;    INNER JOIN `user_likes` `ul`&#8217;.&#8221;n&#8221;.<br />
&#8216;        ON `ul`.`user_id` = `u`.`user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;    INNER JOIN `likes` `l`&#8217;.&#8221;n&#8221;.<br />
&#8216;       ON  `l`.`likes_id` = `ul`.`likes_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;    INNER JOIN `user_dislikes` `ud`&#8217;.&#8221;n&#8221;.<br />
&#8216;        ON `ud`.`user_id` = `u`.`user_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;    INNER JOIN `dislikes` `d`&#8217;.&#8221;n&#8221;.<br />
&#8216;       ON  `d`.`dislikes_id` = `ud`.`dislikes_id`&#8217;.&#8221;n&#8221;.<br />
&#8216;WHERE `u`.`user_id` = 1;&#8217;);</p>
<p>$qry  = mysql_query($sql, $link) or die(&#8220;&lt;pre&gt;SQL:n{$sql}nERROR:n&#8221;.mysql_error($link).&#8217;&lt;/pre&gt;&#8217;);<br />
$cnt  = mysql_num_rows($qry);</p>
<p>echo &#8216;All rows:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}while(&#8211;$cnt &gt; 0);<br />
}<br />
[/php]</p>
<p>Wow! Again, MySQL is making us work some more. With MongoDB we have three approaches. The first way is to fake it with a 1:1 or 1:N with an extra collection with the values you want to validate against.  This might seem odd if you want to do a N:N relation, but there is reason why would want to do this in MongoDB . The second way is to create &#8220;manual relations&#8221;. This is kind of like MyISAM, where there isn&#8217;t an automatic relation, you have to specify it in your query. So lets look that one over.</p>
<p><em>MongoDB</em><br />
[php]<br />
// Create the &#8220;likes&#8221; and &#8220;dislikes&#8221; collections (create, drop and recreate).<br />
$likes = $db-&gt;likes;<br />
$likes-&gt;drop();<br />
$likes = $db-&gt;likes;</p>
<p>$dis   = $db-&gt;dislikes;<br />
$dis-&gt;drop();<br />
$dis   = $db-&gt;dislikes;</p>
<p>// Insert some &#8220;likes&#8221; and &#8220;dislikes&#8221;<br />
// &#8220;Likes&#8221;<br />
$doc  = array(&#8216;likes&#8217; =&gt; &#8216;Ice cream&#8217;);<br />
$likes-&gt;insert($doc, true);</p>
<p>$doc  = array(&#8216;likes&#8217; =&gt; &#8216;Pizza&#8217;);<br />
$likes-&gt;insert($doc, true);</p>
<p>$doc  = array(&#8216;likes&#8217; =&gt; &#8216;Puppies&#8217;);<br />
$likes-&gt;insert($doc, true);</p>
<p>$doc  = array(&#8216;likes&#8217; =&gt; &#8216;Kittens&#8217;);<br />
$likes-&gt;insert($doc, true);</p>
<p>$ls   = $likes-&gt;find();</p>
<p>// &#8220;Dislikes&#8221;<br />
$doc  = array(&#8216;dislikes&#8217; =&gt; &#8216;Oil spills&#8217;);<br />
$dis-&gt;insert($doc, true);</p>
<p>$doc  = array(&#8216;dislikes&#8217; =&gt; &#8216;Screeming children&#8217;);<br />
$dis-&gt;insert($doc, true);</p>
<p>// Create a &#8220;N:N&#8221; for &#8220;likes&#8221; and &#8220;dislikes&#8221; in the &#8220;profile&#8221; element<br />
// Find our &#8220;likes&#8221;<br />
$ic   = $likes-&gt;findOne(array(&#8216;likes&#8217; =&gt; &#8216;Ice cream&#8217;));<br />
$pz   = $likes-&gt;findOne(array(&#8216;likes&#8217; =&gt; &#8216;Pizza&#8217;));<br />
$ps   = $likes-&gt;findOne(array(&#8216;likes&#8217; =&gt; &#8216;Puppies&#8217;));</p>
<p>// Find our &#8220;dislikes&#8221;<br />
// Find our &#8220;likes&#8221;<br />
$os   = $dis-&gt;findOne(array(&#8216;dislikes&#8217; =&gt; &#8216;Oil spills&#8217;));</p>
<p>// Create manual reference<br />
$col-&gt;update(array(&#8216;_id&#8217; =&gt; $id), array(&#8216;$set&#8217; =&gt; array(&#8216;profile&#8217; =&gt; array(&#8216;likes&#8217;    =&gt; array($ic['_id'], $pz['_id'], $ps['_id']),<br />
&#8216;dislikes&#8217; =&gt; array($os['_id'])))));</p>
<p>// Get all documents<br />
$res = $col-&gt;find();</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);</p>
<p>echo &#8220;nLikes:n&#8221;;</p>
<p>foreach($doc['profile']['likes'] as $key=&gt;$val)<br />
{<br />
$l = $likes-&gt;findOne(array(&#8216;_id&#8217; =&gt; $val));<br />
echo $l['likes'].&#8221;n&#8221;;<br />
}</p>
<p>echo &#8220;nDislikes:n&#8221;;</p>
<p>foreach($doc['profile']['dislikes'] as $key=&gt;$val)<br />
{<br />
$d = $dis-&gt;findOne(array(&#8216;_id&#8217; =&gt; $val));<br />
echo $d['dislikes'].&#8221;n&#8221;;<br />
}</p>
<p>echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>The thirday way is to create a reference (DBRef) to another document.<br />
<em>MongoDB</em></p>
<p>[php]<br />
// Create an automatic reference<br />
$col-&gt;update(array(&#8216;_id&#8217; =&gt; $id), array(&#8216;$set&#8217; =&gt; array(&#8216;profile&#8217; =&gt; array(&#8216;likes&#8217;    =&gt; array(array(&#8216;$ref&#8217; =&gt; &#8216;likes&#8217;, &#8216;$id&#8217; =&gt; $ic['_id']),<br />
array(&#8216;$ref&#8217; =&gt; &#8216;likes&#8217;, &#8216;$id&#8217; =&gt; $pz['_id']),<br />
array(&#8216;$ref&#8217; =&gt; &#8216;likes&#8217;, &#8216;$id&#8217; =&gt; $ps['_id'])<br />
),<br />
&#8216;dislikes&#8217; =&gt; array(array(&#8216;$ref&#8217; =&gt; &#8216;dislikes&#8217;, &#8216;$id&#8217; =&gt; $os['_id']))))));</p>
<p>// Get all documents<br />
$res = $col-&gt;find();</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);</p>
<p>echo &#8220;nLikes:n&#8221;;</p>
<p>foreach($doc['profile']['likes'] as $key=&gt;$val)<br />
{<br />
$l = $likes-&gt;findOne(array(&#8216;_id&#8217; =&gt; $val['$id']));<br />
echo $l['likes'].&#8221;n&#8221;;<br />
}</p>
<p>echo &#8220;nDislikes:n&#8221;;</p>
<p>foreach($doc['profile']['dislikes'] as $key=&gt;$val)<br />
{<br />
$d = $dis-&gt;findOne(array(&#8216;_id&#8217; =&gt; $val['$id']));<br />
echo $d['dislikes'].&#8221;n&#8221;;<br />
}</p>
<p>echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>So we&#8217;ve created an element that references a document. The key was to query what we needed, then used &#8220;$ref&#8221; identifier (<a href="http://www.mongodb.org/display/DOCS/Database+References" target="_blank">More information</a>) along with the ID return from our query to create the element. There is another way to do this in PHP by using the &#8220;<a href="http://us3.php.net/manual/en/mongocollection.createdbref.php" target="_blank">MongoCollection::createDBRef</a>&#8221; method.<br />
<em>MongoDB</em></p>
<p>[php]<br />
$col-&gt;update(array(&#8216;_id&#8217; =&gt; $id), array(&#8216;$set&#8217; =&gt; array(&#8216;profile&#8217; =&gt; array(&#8216;likes&#8217;    =&gt; array($likes-&gt;createDBRef($likes-&gt;findOne(array(&#8216;likes&#8217; =&gt; &#8216;Ice cream&#8217;))),<br />
$likes-&gt;createDBRef($likes-&gt;findOne(array(&#8216;likes&#8217; =&gt; &#8216;Pizza&#8217;))),<br />
$likes-&gt;createDBRef($likes-&gt;findOne(array(&#8216;likes&#8217; =&gt; &#8216;Puppies&#8217;)))<br />
),<br />
&#8216;dislikes&#8217; =&gt; array($dis-&gt;createDBRef($dis-&gt;findOne(array(&#8216;dislikes&#8217; =&gt; &#8216;Oil spills&#8217;))))));<br />
[/php]</p>
<p>And we can also clean up our loop with less code:<br />
<em>MongoDB</em></p>
<p>[php]<br />
foreach($doc['profile']['dislikes'] as $key=&gt;$val)<br />
{<br />
$d = $col-&gt;getDBRef($val);<br />
echo $d['dislikes'].&#8221;n&#8221;;<br />
}<br />
[/php]</p>
<p>Of course there is one problem with doing N:N in MongoDB . You can&#8217;t query it with a single query, since there is no &#8220;JOIN&#8221; support. So it would be better to embed the data you need to search on and return. Sure it might be redundant, but it seems that would be the best solution at this time. For more information about when to use DBRef vs Embedding, check out the <a title="MongoDB Schema Design" href="http://www.mongodb.org/display/DOCS/Schema+Design" target="_blank">Schema Design article</a>.</p>
<p>Before we end this tutorial, let me leave you with a little extra, adding to the &#8220;likes&#8221; and &#8220;dislikes&#8221; in the &#8220;profile&#8221;:<br />
<em>MongoDB</em></p>
<p>[php]<br />
// Add (Not replace) another &#8220;likes&#8221; and &#8220;Dislikes&#8221; to the profile.<br />
$col-&gt;update(array(&#8216;_id&#8217; =&gt; $id), array(&#8216;$pushAll&#8217; =&gt; array(&#8216;profile.likes&#8217; =&gt; array($likes-&gt;createDBRef($likes-&gt;findOne(array(&#8216;likes&#8217; =&gt; &#8216;Kittens&#8217;)))),<br />
&#8216;profile.dislikes&#8217; =&gt; array($dis-&gt;createDBRef($dis-&gt;findOne(array(&#8216;dislikes&#8217; =&gt; &#8216;Screeming children&#8217;)))))), array(&#8216;safe&#8217; =&gt; 1));</p>
<p>// Get all documents<br />
$res = $col-&gt;find();</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8220;&lt;pre&gt;Pushed:n&#8221;;<br />
print_r($doc);</p>
<p>echo &#8220;nLikes:n&#8221;;</p>
<p>foreach($doc['profile']['likes'] as $key=&gt;$val)<br />
{<br />
$l = $col-&gt;getDBRef($val);<br />
echo $l['likes'].&#8221;n&#8221;;<br />
}</p>
<p>echo &#8220;nDislikes:n&#8221;;</p>
<p>foreach($doc['profile']['dislikes'] as $key=&gt;$val)<br />
{<br />
$d = $col-&gt;getDBRef($val);<br />
echo $d['dislikes'].&#8221;n&#8221;;<br />
}</p>
<p>echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>You&#8217;ll notice that use used the &#8220;keyword&#8221; of &#8220;$pushAll&#8221; to push our array into the &#8220;likes&#8221; and &#8220;dislikes&#8221; element. Also note that we also used dot notation (&#8220;profile.likes&#8221;) to indicated that &#8220;likes&#8221; and &#8220;dislikes&#8221; are element of &#8220;profile&#8221;. So if we had something like &#8220;animal&#8221; which was an array element of &#8220;likes&#8221; which is part of &#8220;profile&#8221;, we would have done &#8220;profile.likes.animal&#8221;.</p>
<p>Until next time, when we will go over &#8230; I&#8217;m not sure yet, It&#8217;ll be a surprise &#8230; Happy Coding!</p>
<p>If you want a VPS with that has a &#8220;one-click&#8221; install of MongoDB, check out <a href="http://www.dealtaker.com/store/dream-host/l" target="_blank">DreamHost</a>. Also don&#8217;t forget to check out our <a href="http://www.dealtaker.com/technology/" target="_blank">tech blog</a> and <a href="http://www.dealtaker.com/category/computers-office/computers/" target="_blank">Computer related coupons</a>.</p>
<p><a href="http://www.dealtaker.com/blog/2010/05/12/php-mongodb-sitting-in-a-tree-part-1/">Part 1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dealtaker.com/our-blog/2010/06/22/php-mongodb-sitting-in-a-tree-part-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PHP &amp; MongoDB Sitting in a Tree: Part 1</title>
		<link>http://www.dealtaker.com/our-blog/2010/05/12/php-mongodb-sitting-in-a-tree-part-1/</link>
		<comments>http://www.dealtaker.com/our-blog/2010/05/12/php-mongodb-sitting-in-a-tree-part-1/#comments</comments>
		<pubDate>Wed, 12 May 2010 21:08:30 +0000</pubDate>
		<dc:creator>ellisgl</dc:creator>
				<category><![CDATA[DealTaker.com Updates]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[mongo]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[nosql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[scale]]></category>
		<category><![CDATA[Schema-less]]></category>
		<category><![CDATA[schemaless]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.dealtaker.com/blog/?p=2187</guid>
		<description><![CDATA[Yet another MongoDB and PHP tutorial, say it ain&#8217;t so! Well yes, but this tutorial aims to be more complete than the others out there. OK I&#8217;m going to assume you know what MongoDB is, so I&#8217;m not going to go over &#8220;what mongoDB is&#8221; or &#8220;what NoSQL is&#8221;. I&#8217;m going to do this series [...]]]></description>
			<content:encoded><![CDATA[<p>Yet another MongoDB and PHP tutorial, say it ain&#8217;t so! Well yes, but this tutorial aims to be more complete than the others out there. OK I&#8217;m going to assume you know what MongoDB is, so I&#8217;m not going to go over &#8220;what mongoDB is&#8221; or &#8220;what NoSQL is&#8221;. I&#8217;m going to do this series in a little different styling than my other tutorial series have been, so let just jump right in.<br />
<span id="more-2187"></span></p>
<p>Here&#8217;s a couple links to get you up to speed:<br />
<a href="http://www.mongodb.org/display/DOCS/Quickstart">Installing Mongo</a><br />
<a href="http://www.mongodb.org/display/DOCS/PHP+Language+Center">MongoDB PHP Extension</a></p>
<p>If you have issues with MongoD not starting &#8211; something about &#8220;/data/db&#8221; missing, then you should create the directory. In *Nix: &#8220;mkdir /data/db&#8221;, in Win &#8220;mkdir c:data&#8221; then &#8220;mkdir c:datadb&#8221;.</p>
<p><strong>Connecting</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
&lt;?php<br />
$host = &#8216;localhost&#8217;;<br />
$user = &#8216;root&#8217;;<br />
$pass = &#8220;&#8221;;<br />
$link = mysql_connect($host, $user, $pass, 1) or die(&#8220;Could not connect to: {$host}. Check your settings and try again.&#8221;);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
&lt;?php<br />
try<br />
{<br />
$link = new Mongo();<br />
}<br />
catch(MongoConnectionException $e)<br />
{<br />
die(&#8216;Could not connect. Check to make sure MongoDB is running.&#8217;);<br />
}<br />
[/php]</p>
<p>As you can see, Mongo DB automatically will connect to the local host and default port. Yes, MySQL will do the same if you have the directives in your &#8220;php.ini&#8221; setup to do this. IE. &#8220;mysql.default_host&#8221;, &#8220;mysql.default_user&#8221; and &#8220;mysql.default_password&#8221;. You might notice that by default MongoDB doesn&#8217;t have a user name or password setup. I will go over how to set that up in part 2.</p>
<p><strong>Creating and using a DB</strong><br />
<em>MySQL</em></p>
<p>[php]$db  = &#8216;testdb&#8217;;<br />
$sql = &#8220;CREATE DATABASE `$db`&#8221;;</p>
<p>mysql_query($sql, $link);<br />
mysql_select_db($db, $link);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]$db   = $link-&gt;testdb;<br />
[/php]</p>
<p>In one line of code, MongoDB will create a DB automatically if it doesn&#8217;t already exists and select (use) it.</p>
<p><strong>Create a Table / Collection</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Create the Table<br />
$tbl = &#8216;user&#8217;;<br />
$sql = &#8220;CREATE TABLE `$tbl` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `login` VARCHAR (24)NOT NULL, `password` CHAR(32) NOT NULL, `email` VARCHAR(255)) TYPE=innodb;&#8221;;<br />
mysql_query($sql, $link);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Create the collection (AKA Table)<br />
$col  = $db-&gt;user;<br />
[/php]</p>
<p>Once again, MongoDB will automatically create something for us if it doesn&#8217;t exist. In this example, it create our &#8220;user&#8221; table. You might notice we didn&#8217;t define how the table is formatted, this is because MongoDB is schema-less and doesn&#8217;t need column definitions. &#8220;Tables&#8221; in MongoDB are called &#8220;collections&#8221;.</p>
<p><strong>Insert Data</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Insert a row into the table<br />
$sql = &#8220;INSERT INTO `$tbl` SET `login` = &#8216;jsmith&#8217;, `password` = &#8217;5f4dcc3b5aa765d61d8327deb882cf99&#8242;, `email` = &#8216;jsmith@example.com&#8217;&#8221;;<br />
mysql_query($sql);</p>
<p>$sql = &#8220;INSERT INTO `$tbl` SET `login` = &#8216;psmith&#8217;, `password` = &#8217;5f4dcc3b5aa765d61d8327deb882cf99&#8242;, `email` = &#8216;psmith@example.com&#8217;&#8221;;<br />
mysql_query($sql);</p>
<p>// Get the ID of last insert<br />
$id = mysql_insert_id($link);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Insert a document (row) into the collection (table)<br />
$doc  = array(&#8216;login&#8217; =&gt; &#8216;jsmith&#8217;, &#8216;password&#8217; =&gt; &#8216; 5f4dcc3b5aa765d61d8327deb882cf99&#8242;, &#8216;email&#8217; =&gt; &#8216;jsmith@example.com&#8217;);<br />
$col-&gt;insert($doc, true);</p>
<p>$doc  = array(&#8216;login&#8217; =&gt; &#8216;psmith&#8217;, &#8216;password&#8217; =&gt; &#8216; 5f4dcc3b5aa765d61d8327deb882cf99&#8242;, &#8216;email&#8217; =&gt; &#8216;psmith@example.com&#8217;);<br />
$col-&gt;insert($doc, true);</p>
<p>// Get the id of last insert<br />
$id   = $doc['_id'];<br />
[/php]</p>
<p>You might have noticed that we used an array to define our &#8220;row&#8221; of data, which are called &#8220;documents&#8221;. On the insert method, the second argument will set the query to do a &#8220;safe insert&#8221;. This will allow us to find out if the query executed properly. If not set, it will not get that information. So I would set it to true if you want to be able to debug your queries. If you are wondering about the password, it&#8217;s the MD5 hash for &#8220;password&#8221;.</p>
<p><strong>Querying Data</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Get all rows<br />
$sql = &#8220;SELECT * FROM `$tbl`&#8221;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All rows:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;<br />
}<br />
}</p>
<p>// Query for the row matching the last insert ID<br />
$sql = &#8220;SELECT * FROM `$tbl` WHERE `id` = {$id}&#8221;;<br />
$qry = mysql_query($sql, $link);<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;Single row (id = $id):&amp;lt;br/&amp;gt;&amp;lt;pre&amp;gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Get all documents<br />
$res = $col-&gt;find();</p>
<p>echo &#8216;All documents:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}</p>
<p>// Query for the document matching the last insert ID<br />
$doc  = $col-&gt;findone(array(&#8216;_id&#8217; =&gt; $id));</p>
<p>echo &#8216;Single document (_id = $id):&lt;br/&gt;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
[/php]</p>
<p>The MongoDB support in PHP has function to pull a single document, or all the documents. Once again, we use arrays to define something, in this example, we define our constraint.</p>
<p><strong>Upading Data</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
$sql = &#8220;UPDATE `$tbl` SET `password` = &#8216;b497dd1a701a33026f7211533620780d&#8217; WHERE `id` = {$id}&#8221;;<br />
$qry = mysql_query($sql, $link);</p>
<p>$sql = &#8220;SELECT * FROM `$tbl` WHERE `id` = {$id}&#8221;;<br />
$qry = mysql_query($sql, $link);<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;Updated row (id = $id):&lt;br/&gt;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;<br />
[/php]</p>
<p><em>MogoDB</em></p>
<p>[php]<br />
// Update a document<br />
$col-&gt;update(array(&#8216;_id&#8217; =&gt; $id), array(&#8216;$set&#8217; =&gt; array(&#8216;password&#8217; =&gt; &#8216;b497dd1a701a33026f7211533620780d&#8217;)));</p>
<p>// Query the updated docuemnt<br />
$doc = $col-&gt;findone(array(&#8216;_id&#8217; =&gt; $id));</p>
<p>echo &#8216;Updated docuement:&lt;br/&gt;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
[/php]</p>
<p>The MongoDB extension has a function to perform updates. The first argument is an array of constraints, IE &#8220;WHERE {expression}&#8221;. The second is the data we want to update and what we want to update it with. Pretty simple, right?</p>
<p><strong>Indexing data</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Create a unique index<br />
$sql = &#8220;ALTER TABLE `$db`.`$tbl` ADD UNIQUE `login` (`login`)&#8221;;<br />
$qry = mysql_query($sql, $link);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Create a unique index<br />
$col-&gt;ensureIndex(array(&#8220;login&#8221; =&gt; 1), array(&#8220;unique&#8221; =&gt; true, &#8220;dropDups&#8221; =&gt; true));<br />
[/php]</p>
<p>MongoDB has method for creating index name &#8220;ensureIndex&#8221;. The first parameter is an array of what we want to index and the value is ether 1 or -1. 1 means that the index will sort the data for this in an ascending manor, while -1 will sort it in a descending manor. The second parameter are extra options. In this example I tell it to make what ever I&#8217;m indexing as a unique index, that way I don&#8217;t end up with multiple &#8220;jsmith&#8221; entries. Also, I&#8217;ve told it to drop any documents that have duplicates of the data in the &#8220;login&#8221; &#8220;column&#8221;. Another note is that &#8220;columns&#8221; in MongoDB should be called &#8220;elements&#8221;, since we are really dealing with arrays.</p>
<p>Lets make sure our index is working shall we?<br />
<em>MongoDb</em></p>
<p>[php]<br />
// Test our unique index<br />
try<br />
{<br />
$doc  = array(&#8216;login&#8217; =&gt; &#8216;jsmith&#8217;, &#8216;password&#8217; =&gt; &#8216; 5f4dcc3b5aa765d61d8327deb882cf99&#8242;, &#8216;email&#8217; =&gt; &#8216;jsmith@example.com&#8217;);<br />
$col-&gt;insert($doc, true);<br />
}<br />
catch(MongoCursorException $e)<br />
{<br />
echo &#8216;Could not insert document. Double check values.&lt;br /&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>If all works, we should get an error message.</p>
<p><strong>Limiting Results</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Limits<br />
$sql = &#8220;SELECT * FROM `$tbl` LIMIT 1&#8243;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All rows &#8211; Limit by 1:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;<br />
}<br />
}<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Limits<br />
$res = $col-&gt;find()-&gt;limit(1);</p>
<p>echo &#8216;All documents &#8211; Limited to 1:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p><strong>Offsetting</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Limits<br />
$sql = &#8220;SELECT * FROM `$tbl` OFFSET 1 LIMIT 1&#8243;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All rows &#8211; Limit by 1 &#8211; Offset by 1:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
}<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Offsets<br />
$res = $col-&amp;gt;find()-&amp;gt;skip(1)-&amp;gt;limit(1);</p>
<p>echo &#8216;All documents &#8211; Limited to 1, Offset by 1:&lt;br/ &gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
&lt;/pre&gt;<br />
[/php]</p>
<p>To offset a your query start point, we used the method &#8220;skip&#8221; with an integer value to create the offset.</p>
<p><strong>Sorting</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Sorting<br />
$sql = &#8220;SELECT * FROM `$tbl` ORDERBY `login` DESC&#8221;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All rows &#8211;  Sorted by login descending:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;<br />
}while(&#8211;$cnt &gt; 0);<br />
}<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Sorting<br />
$res = $col-&gt;find()-&gt;sort(array(&#8216;login&#8217; =&gt; -1));</p>
<p>echo &#8216;All documents &#8211; Sorted by login descending:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>Here we used the sort method, told it what element to sort on and which direction, -1 being descending. The record for &#8220;psmith&#8221; should show up first. A word of caution here, there is a 4MB limit if sorting on non-indexed element.</p>
<p><strong>Advanced Queries</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Advanced queries<br />
// Add new column<br />
$sql = &#8220;ALTER `$db`.`$tbl` ADD COLUMN `age` INT UNSIGNED&#8221;;<br />
mysql_query($sql, $link);</p>
<p>// Add values<br />
$sql = &#8220;UPDATE `$tbl` SET `age` = 40 WHERE `login` = &#8216;jsmith&#8217;&#8221;;<br />
mysql_query($sql, $link);</p>
<p>$sql = &#8220;UPDATE `$tbl` SET `age` = 24 WHERE `login` = &#8216;psmith&#8217;&#8221;;<br />
mysql_query($sql, $link);</p>
<p>// Query for anyone under 30<br />
$sql = &#8220;SELECT * FROM `$tbl` WHERE `age` &lt; 30&#8243;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All documents &#8211; Anyone under 30:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
}</p>
<p>// Query for anyone over 30<br />
$sql = &#8220;SELECT * FROM `$tbl` WHERE `age` &gt; 30&#8243;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All documents &#8211; Anyone over 30:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
}</p>
<p>// Query from anyone 25 and over<br />
$sql = &#8220;SELECT * FROM `$tbl` WHERE `age` &gt;= 25&#8243;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All documents &#8211; Anyone 25 and over:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
}<br />
// Query for anyone 25 and under<br />
$sql = &#8220;SELECT * FROM `$tbl` WHERE `age` &lt;= 25&#8243;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All documents &#8211; Anyone 25 and under:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
}</p>
<p>// Query for anyone not 40<br />
$sql = &#8220;SELECT * FROM `$tbl` WHERE `age` != 40&#8243;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All documents &#8211; Anyone not 30:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
}</p>
<p>// Query for anyone 20-50<br />
$sql = &#8220;SELECT * FROM `$tbl` WHERE `age` &gt;= 20 AND `age` &lt;= 50&#8243;;<br />
$qry = mysql_query($sql, $link);<br />
$cnt = mysql_num_rows($qry);</p>
<p>echo &#8216;All documents &#8211; Anyone 20-50:&lt;br/&gt;&#8217;;</p>
<p>if($cnt &gt; 0)<br />
{<br />
do<br />
{<br />
$row = mysql_fetch_assoc($qry);</p>
<p>echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($row);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
}<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Advanced queries<br />
// Add a new element and value<br />
$col-&gt;update(array(&#8216;login&#8217; =&gt; &#8216;jsmith&#8217;), array(&#8216;$set&#8217; =&gt; array(&#8216;age&#8217; =&gt; 40)));<br />
$col-&gt;update(array(&#8216;login&#8217; =&gt; &#8216;psmith&#8217;), array(&#8216;$set&#8217; =&gt; array(&#8216;age&#8217; =&gt; 24)));</p>
<p>// Confirm<br />
$res = $col-&gt;find();</p>
<p>echo &#8216;All documents &#8211; Confirming age element:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}</p>
<p>// Query for anyone under 30<br />
$res = $col-&gt;find(array(&#8216;age&#8217; =&gt; array(&#8216;$lt&#8217; =&gt; 30)));</p>
<p>echo &#8216;All documents &#8211; Anyone under 30:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}</p>
<p>// Query for anyone over 30<br />
$res = $col-&gt;find(array(&#8216;age&#8217; =&gt; array(&#8216;$gt&#8217; =&gt; 30)));</p>
<p>echo &#8216;All documents &#8211; Anyone over 30:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}</p>
<p>// Query from anyone 25 or over<br />
$res = $col-&gt;find(array(&#8216;age&#8217; =&gt; array(&#8216;$gte&#8217; =&gt; 25)));</p>
<p>echo &#8216;All documents &#8211; Anyone 25 or older:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}</p>
<p>// Query for anyone 25 and under<br />
$res = $col-&gt;find(array(&#8216;age&#8217; =&gt; array(&#8216;$lte&#8217; =&gt; 25)));</p>
<p>echo &#8216;All documents &#8211; Anyone 25 or younger:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}</p>
<p>// Query for anyone not 40<br />
$res = $col-&gt;find(array(&#8216;age&#8217; =&gt; array(&#8216;$ne&#8217; =&gt; 40)));</p>
<p>echo &#8216;All documents &#8211; Anyone not 40:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}</p>
<p>// Query for anyone 20-50<br />
$res = $col-&gt;find(array(&#8216;age&#8217; =&gt; array(&#8216;$gte&#8217; =&gt; 20, &#8216;$lte&#8217; =&gt; 50)));</p>
<p>echo &#8216;All documents &#8211; Anyone 20-50:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>With MongoDB you can do &#8220;&lt;,&lt;=, &gt;, &gt;=&#8221; conditional operator based queries. Only thing is that you can&#8217;t just use &#8220;&lt;,&lt;=, &gt;, &gt;=&#8221; in your constraints, you have to use MongoDB&#8217;s version. Those are &#8220;$lt&#8221; (less than), &#8220;$lte&#8221; (less than or equal), &#8220;$gt&#8221; (greater than), &#8220;$gte&#8221; (greater than or equal). Yes, you need the dollar sign. Other conditional operators are &#8220;$ne&#8221; (not equal to), &#8220;$in&#8221; (like MySQL&#8217;s IN statement), &#8220;$nin&#8221; (NOT IN), &#8220;$mod&#8221; (Modulo operation), &#8220;$all&#8221; (like in, but all values much be matched to a document),  &#8220;$size&#8221; (Match of number of elements), &#8220;$exists&#8221; (element exists), &#8220;$type&#8221; (matches element type &#8211; int, string, etc) and there are couple more.</p>
<p><strong>Deleting a Row / Docuement</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Delete a row<br />
$sql = &#8220;DELETE FROM `$tbl` WHERE `login` = &#8216;psmith&#8217;&#8221;<br />
mysql_query($sql, $link);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Delete a document<br />
$col-&gt;remove(array(&#8216;age&#8217; =&gt; 24), array(&#8216;justOne&#8217; =&gt; true, &#8216;safe&#8217; =&gt; true));</p>
<p>// Confirm delete<br />
$res = $col-&gt;find();</p>
<p>echo &#8216;All documents:&lt;br/&gt;&#8217;;</p>
<p>foreach($res as $doc)<br />
{<br />
echo &#8216;&lt;pre&gt;&#8217;;<br />
print_r($doc);<br />
echo &#8216;&lt;/pre&gt;&#8217;;<br />
}<br />
[/php]</p>
<p>Here we use the &#8220;remove&#8221; method. First argument has the constraints and the second tell it to only remove one item and also to run a &#8220;safe&#8221; query.</p>
<p><strong>Dropping a Table / Collection</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Drop table<br />
$sql = &#8220;DROP TABLE `$db`.`$tbl`&#8221;;<br />
mysql_query($sql, $link);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Drop collection<br />
$col-&gt;drop();<br />
[/php]</p>
<p><strong>Dropping a database</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Drop DB<br />
$sql = &#8220;DROP DATABASE `$db`&#8221;;<br />
mysql_query($sql, $link);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Drop DB<br />
$db-&gt;drop();<br />
[/php]</p>
<p><strong>Disconnect</strong><br />
<em>MySQL</em></p>
<p>[php]<br />
// Disconnect<br />
mysql_close($link);<br />
[/php]</p>
<p><em>MongoDB</em></p>
<p>[php]<br />
// Disconnect<br />
$link-&gt;close();<br />
[/php]</p>
<p>Until next time, when I will go over more stuff, happy coding.</p>
<p>Sources:<br />
<a href="http://www.php.net/manual/en/book.mongo.php" target="_blank">PHP.net</a>, <a href="http://www.mongodb.org/display/DOCS/Home" target="_blank">MongoDB</a></p>
<p><a href="http://www.dealtaker.com/blog/2010/06/22/php-mongodb-sitting-in-a-tree-part-2/">Part 2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dealtaker.com/our-blog/2010/05/12/php-mongodb-sitting-in-a-tree-part-1/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>Kohana PHP Tuturial &#8211; Part III</title>
		<link>http://www.dealtaker.com/our-blog/2009/06/19/kohana-php-tuturial-part-iii/</link>
		<comments>http://www.dealtaker.com/our-blog/2009/06/19/kohana-php-tuturial-part-iii/#comments</comments>
		<pubDate>Fri, 19 Jun 2009 08:26:09 +0000</pubDate>
		<dc:creator>ellisgl</dc:creator>
				<category><![CDATA[DealTaker.com Updates]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[kohana]]></category>
		<category><![CDATA[models]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.dealtaker.com/blog/?p=1013</guid>
		<description><![CDATA[It&#8217;s been a couple weeks now, so lets get back on track with this series of tutorials. This tutorial will get into models and how to play with data. The first thing I have to is tell you is that Kohana PHP has been updated since the last tutorial. So I have gone ahead and [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a couple weeks now, so lets get back on track with this series of tutorials. This tutorial will get into models and how to play with data.<br />
<span id="more-1013"></span></p>
<p>The first thing I have to is tell you is that Kohana PHP has been updated since the last tutorial. So I have gone ahead and took the last tutorial and updated the core and made sure it worked with Kohana 2.3.4. <a href="http://images.dealtaker.com/dealtaker/blog/kohana/dealtaker-kohana-2-2.3.4.zip">You can grab that here</a>. Now onward to the glory!</p>
<p>The first thing we want to do is identify where and what the data is. Is it an XML feed, CSV, JSON, DB or something else? Well I&#8217;m going to make it easy. We are going to deal with our friend MySQL for this. The next step is to setup a MySQL DB connection.</p>
<p>Go into your system/config folder and copy the database.php file to your application/config folder. Edit the application/config/database.php to reflect your server settings. Mine looks like this:</p>
<pre>$config['default'] = array
(
	'benchmark'     =&gt; TRUE,
	'persistent'    =&gt; FALSE,
	'connection'    =&gt; array
	(
		'type'     =&gt; 'mysql',
		'user'     =&gt; 'root',
		'pass'     =&gt; 'root',
		'host'     =&gt; 'localhost',
		'port'     =&gt; FALSE,
		'socket'   =&gt; FALSE,
		'database' =&gt; 'myfirstkohana'
	),
	'character_set' =&gt; 'utf8',
	'table_prefix'  =&gt; '',
	'object'        =&gt; TRUE,
	'cache'         =&gt; FALSE,
	'escape'        =&gt; TRUE
);</pre>
<p>Now that we have a configuration a connection for our database, we should probably set up a database and a table. Here&#8217;s the SQL:</p>
<pre>/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`myfirstkohana` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `myfirstkohana`;

/*Table structure for table `posts` */
DROP TABLE IF EXISTS `posts`;

CREATE TABLE `posts` (
  `id` mediumint(8) unsigned NOT NULL auto_increment,
  `title` varchar(255) default NULL,
  `post` text,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;

/*Data for the table `posts` */
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;</pre>
<p>This is a pretty straight forward &#8220;Create a DB and one table&#8221; setup. You might notice that we have everything set for UTF8. This will match the DB configuration setting and also will allow us to deal with i18n (Internationalization) stuff later on.</p>
<p>Onward to creating an actual model. There are a couple things to keep in mind with naming conventions, well really one. From the docs &#8220;The model class name is capitalized, does have _Model appended to it and should be the singular form of the name.&#8221;. There are so other rules when you are dealing with ORM, but we won&#8217;t be dealing with ORM in this tutorial.</p>
<p>Create a file named post.php in the &#8216;application/models/&#8217; folder and make it look like the following:</p>
<pre>&lt;?php
defined('SYSPATH') or die('No direct script access.');

class Post_Model extends Model
 {
    public function __construct()
    	{
		      parent::__construct();
    	}

 }</pre>
<p>As you can tell the above really doesn&#8217;t do much, so let&#8217;s give it some functionality:</p>
<pre>&lt;?php
defined('SYSPATH') or die('No direct script access.');

class Post_Model extends Model
 {
    public function __construct()
    	{
		      parent::__construct();
    	}

    public function getPosts()
     {
        $sql = 'SELECT *
                FROM   `posts`
                LIMIT  0, 10';

        return $this-&gt;db-&gt;query($sql);
     }
 }</pre>
<p>So we have a model method that pulls 10 posts from the table with a pretty simple query. We use &#8220;$this-&gt;query()&#8221; to run queries, which will return object and we return that to the calling entity. Check the query method <a href="http://docs.kohanaphp.com/libraries/database/query" target="_blank">docs here</a> for more information.</p>
<p>Let&#8217;s update our &#8216;Hello&#8217; controller to use this the model.</p>
<p>In your application/controllers/hello.php update your index() method to look like this:</p>
<pre>    public function index()
     {
        // Load the models
        $post  = new Post_Model;
        $posts = $post-&gt;getPosts();
        $rpsts = "";

        // Loop thru the posts
        foreach($posts-&gt;result_array(FALSE) as $row)
         {
          // Simple output of
          $rpsts .= '
    &lt;h1&gt;'.$row['title'].'&lt;/h1&gt;
    '.$row['post'].'&lt;hr /&gt;';
         }

        // Put something useful in our variables.
        $this-&gt;template-&gt;header-&gt;pageTitle .= ' ::: I am on the top';
        $this-&gt;template-&gt;content-&gt;content   = $rpsts;
     }</pre>
<p>When we run the hello controller, we won&#8217;t get much but &#8216;This is my second view&#8217;. We need to put stuff in the table. Use your favorite method of accessing your DB and insert some rows. Now when you run it you will see stuff!</p>
<p>If you notice there is a &#8220;$post-&gt;result_array()&#8221; inside a foreach loop. This allows us to loop though the results of the query easily from within the controller.</p>
<p>You might have notice something of bad practice. I pretty much created HTML inside the controller. As we all know, we shouldn&#8217;t do this. Let&#8217;s fix this!</p>
<p>Create a new view named main_posts.php and make it look like:</p>
<pre>&lt;?php foreach($posts as $post): ?&gt;
&lt;h1&gt;&lt;?php echo $post['title'];?&gt;&lt;h1&gt;
&lt;?php echo $post['post'];?&gt;&lt;hr /&gt;
&lt;?php endforeach; ?&gt;</pre>
<p>This view does a foreach on our query results and fills in our little view.</p>
<p>In the the index method of our controller we will need to change up the controller to use our new view.</p>
<pre>   public function index()
     {
        // Load the models
        $post  = new Post_Model;
        $posts = $post-&gt;getPosts();

        // Put something useful in our variables.
        $this-&gt;template-&gt;header-&gt;pageTitle .= ' ::: I am on the top';

        // Posts view
        $this-&gt;template-&gt;content-&gt;content        = new View('main_posts');
        $this-&gt;template-&gt;content-&gt;content-&gt;posts = $posts-&gt;result_array(FALSE);
     }</pre>
<p>As you can tell, it&#8217;s pretty simple and it&#8217;s clean! Here&#8217;s a quick sample on how to do an insert. We are going to add a method to the post model called addPost.</p>
<pre>  public function addPost($title, $post)
    {
       $sql = sprintf('INSERT INTO `posts`
                       SET         `title` = %s,
                                   `post`  = %s',
                       $this-&gt;db-&gt;escape($title),
                       $this-&gt;db-&gt;escape($post));
      $this-&gt;db-&gt;query($sql);
    }</pre>
<p>We need to add a method to handle adding of posts to our hello controller:</p>
<pre>   public function addpost()
     {
        // Load the models
        $post  = new Post_Model;
        $post-&gt;addPost($_POST['title'], $_POST['post']);
        url::redirect('hello');
     }</pre>
<p>And lets add a form to the end of the main_post.php in the views:</p>
<pre>&lt;form method="POST" action="&lt;?php echo url::base();?&gt;hello/addpost/"&gt;
  &lt;table&gt;
    &lt;tr&gt;
     &lt;th&gt;
       Title
     &lt;/th&gt;
     &lt;th&gt;
       Post
     &lt;/th&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
     &lt;td&gt;
      &lt;input type="text" name="title" /&gt;
     &lt;/td&gt;
     &lt;td&gt;
      &lt;textarea cols="20" rows="5" name="post"&gt;&lt;/textarea&gt;
      &lt;input type="submit" name="submit" value="Submit"/&gt;
     &lt;/td&gt;
  &lt;/table&gt;
&lt;/form&gt;</pre>
<p>Once again, pretty simple right? I could go on and give you how to edit entries, but I&#8217;m leaving that to you for your home work. Free free to post your results! Until next time when will go over libraries and helpers, keep on coding till your fingers bleed!</p>
<p>If you enjoyed this tutorial, please check out our <a href="http://www.dealtaker.com/tech-deals.html" target="_blank">tech deals</a> and <a href="http://www.dealtaker.com/Computer-store-coupons-10.html" target="_blank">Computer related coupons</a>.</p>
<p><a href="http://images.dealtaker.com/dealtaker/blog/kohana/dealtaker-kohana-3.zip">Get the file for this tutorial here.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dealtaker.com/our-blog/2009/06/19/kohana-php-tuturial-part-iii/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
	</channel>
</rss>

