<?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>LightCube Solutions Blog</title>
	<atom:link href="http://www.lightcubesolutions.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.lightcubesolutions.com/blog</link>
	<description>Hints, experiences and insights from LightCube Solutions</description>
	<lastBuildDate>Sat, 14 Aug 2010 00:18:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Working With MongoDates and Lithium</title>
		<link>http://www.lightcubesolutions.com/blog/?p=373</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=373#comments</comments>
		<pubDate>Sat, 14 Aug 2010 00:11:22 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Lithium]]></category>
		<category><![CDATA[MongoDate]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=373</guid>
		<description><![CDATA[Mission: Find all the items in a users shopping cart that expired 3 minutes ago. If you want to cheat just scroll to the last code block. Now for the setup. This is a common query for any ecommerce website that wants to keep things &#8220;fresh&#8221; or run some analytics. Private sales sites are fond [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Mission: </strong></em><em>Find all the items in a users shopping cart that expired 3 minutes ago.</em></p>
<p>If you want to cheat just scroll to the last code block. <img src='http://www.lightcubesolutions.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Now for the setup.</p>
<p>This is a common query for any ecommerce website that wants to keep things &#8220;fresh&#8221; or run some analytics. Private sales sites are fond of this because an item in a shopping cart means that a customer is holding up inventory. That of course is a bad thing. This is just one of MANY reason why searching by date range is important.</p>
<p>So how do we handle this with <a href="http://lithify.me" target="_blank">Lithium our RAD PHP 5.3+ framework</a> and MongoDB? To answer this lets use the mission above as our basis and spit out some code. Since you didn&#8217;t skip ahead lets build up our example just a little.</p>
<p>Let&#8217;s start in a BaseModel that will hold our core code. We will first assume that we want to query for some standard time values. To get things started we can setup a human readable protected array:</p>
<pre class="php:nogutter">	protected $_dates = array(
		'now' =&gt; 0,
		'-1min' =&gt; -60,
		'-3min' =&gt; -180,
		'-5min' =&gt; -300,
		'15min' =&gt; 900
	);</pre>
<div>That times above are second that we will either add or subtract from the php method time(). Our calculation will basically be time() + $_dates['key']. The result of that calculation needs to be converted into a <a href="http://php.net/manual/en/class.mongodate.php" target="_blank">MongoDate object</a>. This is important for several reasons. One good reason is that its easier for us to query using dates if Mongo knows we are looking for date. We may also save ourselves some trouble if more native MongoDB temporal calculations are added to the core.</div>
<div><strong><span style="font-weight: normal;"><br />
</span></strong></div>
<div>Using the MongoDate object you can do things like greater than ($gt), less than ($lt) etc, etc and well etc. So how do we create this object? We need to instantiate the date with the Mongo Driver PHP MongoDate class. Since we are using static methods in our Model we&#8217;ll use the following code to create and return our MongoDate based on the name-key we pass the method. We can place this method in the BaseModel as well.</div>
<pre class="php:nogutter">	public static function dates($name) {
	     return new MongoDate(time() + static::_object()-&gt;_dates[$name]);
	}</pre>
<div>That done, we can now save and query for data. The code below demonstrates how we can add some created and expire MongoDates to a cart document. The really important part to glean here is that we are calling our static method to create the MongoDate. This method will live in our CartModel which can extend the BaseModel.</div>
<pre class="php:nogutter">	public static function addDates($product, array $options = array()) {
		$product-&gt;expires = static::dates('15min');
		$product-&gt;created = static::dates('now');
		return static::_object()-&gt;save($product);
	}</pre>
<p><strong>Note: The MongoDate object will look something like &#8220;Thu Aug 05 2010 01:32:41 GMT-0400 (EDT)&#8221;. This throws a few folks off thinking its just a string.</strong></p>
<p>Now for our mission. Don&#8217;t worry I&#8217;ll repeat it here to save you from looking: <em>Find all the items in a users shopping cart that expired 3 minutes ago. </em>How would we do that in the CartsController? All we need to do is call a static method in the CartModel that does the search and let it know what range we are looking for:</p>
<pre class="php:nogutter">    $cart = Cart::search(array('time' =&gt; '-3min'));</pre>
<p>We&#8217;re going to let our model do the heavy lifting to get the data.</p>
<pre class="php:nogutter">	public static function search($params = null) {
		$time = (!empty($params['time'])) ? $params['time'] : 'now';
		$user = Session::read('userLogin');
		return static::all(array(
			'conditions' =&gt; array(
				'session' =&gt; Session::key(),
				'expires' =&gt; array('$gte' =&gt; static::dates($time)),
				'user' =&gt; $user['_id'])),
			'order' =&gt; array('expires' =&gt; 'ASC')
		));
	}</pre>
<p>There is a bit going on here so lets break it down. First we are checking to make sure that the time is there and set it if it&#8217;s not. Then for the sake of finding a specific users cart item we doing some ID grabbing from the PHP Session. Next is the query part: Give me all the user cart items that are greater than X date.</p>
<p>Notice in the code above that we are calling static::dates($time) to fetch our MongoDate. This will let MongoDB in turn know that we are searching for a date and query for it appropriately. This helps to cut out all the epoch timestamp manipulation in our code to properly search for values.</p>
<p>Whew! Now you are an expert and have enough ammunition to use MongoDates to the full.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=373</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Medicine of a Document Database</title>
		<link>http://www.lightcubesolutions.com/blog/?p=350</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=350#comments</comments>
		<pubDate>Sat, 31 Jul 2010 21:11:25 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[document database]]></category>
		<category><![CDATA[MongoDB]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=350</guid>
		<description><![CDATA[I&#8217;ve been meeting folks who are having a hard time understanding the practicality of a document database and dynamic schema. I often hear, &#8220;I&#8217;m just trying to wrap my head around the concept.&#8221; Some of the main concerns are: Shouldn&#8217;t we be normalizing? What about joins? What about ORM? To help with the introduction and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been meeting folks who are having a hard time understanding the practicality of a document database and dynamic schema. I often hear, &#8220;I&#8217;m just trying to wrap my head around the concept.&#8221;</p>
<p>Some of the main concerns are:</p>
<ul>
<li>Shouldn&#8217;t we be normalizing?</li>
<li>What about joins?</li>
<li>What about ORM?</li>
</ul>
<p>To help with the introduction and transition we&#8217;ll need to do a little unraveling than wrapping. Let&#8217;s kick off this short discussion with a literal example of why a document store (in this case MongoDB) works well.</p>
<p>Imagine for a moment that it&#8217;s time for your yearly visit to the doctor. You&#8217;ve been put on a few supplements to improve your health and the doctor is monitoring your progress. Time for a checkup.</p>
<p>You walk into the clinic and give your name. The secretary looks you up in their booking system and confirms your internal patient number. &#8220;There you are Mr. Solutions (Patient #000-00-0001). You&#8217;re right on time, please have a seat.&#8221; says the secretary. Since they have more than one Mr. Solutions its a good thing they have some sort of ID. The secretary goes to get your file as you wait patiently to be called in.</p>
<p>Let me clue you into something that happens behind the scenes. Having worked in a hospital I know the secretary goes into the back-office (database) and searches for the file #000-00-0001 (query). They only get one file. They don&#8217;t get a set of files that have a primary key and join them together. There are no joins. They don&#8217;t put your name/id number into a mapper and look you up.</p>
<p>If you took a peek into the back-office there are small files and big files. Some files have yellow sticky notes and others have blue. They are (indexed) by patient number. While a handful of files look very similar in structure (schema) others seem to be quite different. One way or another there is just one file per patient.</p>
<p>What&#8217;s the point? Welcome to a document database that works.</p>
<p>Many medical professionals made the choice  that a single file/folder/grouping of papers was sufficient to store your medical history. Some clinics are messy, others are neat, yet this simple system works for them. Back at the clinic it seems there is some information needed from a cardiologist that is in their files.</p>
<p>The secretary quickly calls and asks for a copy of the information. When he gets the copy he places it in your file.</p>
<p>You probably got the point a few paragraphs ago.</p>
<p>The same concept holds true with a document database. More often than not (yes there are exceptions) you&#8217;ll find that storing a majority of the pertinent data in a single document works well. What do I mean by a single document?</p>
<p>Taking our medical example, this is what it could look like if your medical history was digitized using the document database &#8211; <a href="www.mongodb.org" target="_blank">MongoDB</a>.</p>
<pre class="code">{
"_id" : ObjectId("4c537d4b82fd211170000000"),
	"name" : "Mr. LightCube Solutions"
	"date_created" : "Sat Jan 2 2010 21:32:58 GMT-0400 (EDT)",
        "DOB" : "Sat Jan 1 1970 00:01:01 GMT-0400 (EDT)",
	"billing" : {
		"description" : "Home",
		"telephone" : "",
		"address" : "43 Happy Lane",
		"address_2" : "",
		"city" : "Light Land",
		"state" : "NY",
		"zip" : "111222",
		"country" : "USA",
	},
	"medications" : [
		{
			"_id" : "4c537b3382fd21df6f040000",
			"name" : "Activase"
			"description" : " tissue plasminogen activator",
			"dose" : "100mg Vial",
			"date_started" : "Fri Jul 30 2010 21:32:58 GMT-0400 (EDT)"
		}
	]
	"appointments" : [
		{
			"date" : "Fri Jul 30 2010 21:32:58 GMT-0400 (EDT)",
			"summary" : "Started patient on Activase due to heart disease."
			"scheduled_checkup" : "Mon Aug 30 2010 11:00:00 GMT-0400 (EDT)",
		}

	]
	"conditions" : {
		High Blood Pressure,
		Diabetes,
		Excessive Vitamin D
	}
}</pre>
<p>What would that document look like in a SQL database? I would guess 4 or 5 different tables requiring joins would be in place.</p>
<p>Why normalize all that valuable information?</p>
<p>If its not practical to do this in reality then why do it digitally?</p>
<p>Store your data in a way that is practical and dynamic. For instance, maybe Mr. Solutions will be put on some special program that will need to be monitored different than previous trials. Why build a new database just for that? Just adapt the schema and embed.</p>
<p>A document database offers the flexibility, speed and simplicity that we already live by in other systems.</p>
<p>Hopefully this brief trip to the doctor helped to clear things up. Now go take your MongoDB medicine and call me in the morning. <img src='http://www.lightcubesolutions.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=350</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Use the MongoDB MD5 field in GridFS</title>
		<link>http://www.lightcubesolutions.com/blog/?p=352</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=352#comments</comments>
		<pubDate>Fri, 30 Jul 2010 14:33:28 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Lithium]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=352</guid>
		<description><![CDATA[If you were like me you started throwing all kinds of files into MongoDB with GridFS. When you took a look at the db.fs.files collection you saw something like this for a document: { "_id" : ObjectId("4c40affcce64e5e275c60100"), "filename" : "My First File.jpg", "uploadDate" : "Fri Jul 16 2010 15:16:12 GMT-0400 (EDT)", "length" : 55162, "chunkSize" [...]]]></description>
			<content:encoded><![CDATA[<p>If you were like me you started throwing all kinds of files into <a href="http://www.mongodb.org/display/DOCS/GridFS+Specification" target="_blank">MongoDB with GridFS</a>. When you took a look at the db.fs.files collection you saw something like this for a document:</p>
<pre name="code" class="javascript:nogutter">
{
	"_id" : ObjectId("4c40affcce64e5e275c60100"),
	"filename" : "My First File.jpg",
	"uploadDate" : "Fri Jul 16 2010 15:16:12 GMT-0400 (EDT)",
	"length" : 55162,
	"chunkSize" : 262144,
	"md5" : "46aa378be7f6f1f3660efd7de5c1cbb6"
}
</pre>
<p>Did you see the MD5 hash? It&#8217;s there for a reason you know.</p>
<p>Since my PHP/MongoDB application has an administrative backend multiple people are loading up files. There is always a possibility that they will upload the same file. Of course this would be a very inefficient use of storage especially when the file is a video or picture.  That&#8217;s where the MD5 field in fs.files comes in handy.</p>
<p>In PHP you can use the <a href="http://php.net/manual/en/function.md5-file.php" target="_blank">md5_file()</a> method to get the MD5 hash <span style="text-decoration: underline;">before you save the file</span> to MongoDB. Running a findOne query using the md5 of your tmp file will let you know if  a document for that file already exists. If it does exist, then you&#8217;ll get back the fs.files document of the preloaded file. Then you can use the _id as a reference and don&#8217;t bother saving the file. Can you imagine all the money you save in storage fees on Amazon S3?</p>
<p>This is a very common and reliable way of doing things since byte for byte you know the files are the same. The sample script below is a snapshot of code in a Lithium application (<a title="Lithium" href="http://lithify.me" target="_blank">Lithium is a new PHP 5.3+ framework</a>). I&#8217;m basically running a findOne({&#8220;md5&#8243; : &#8220;$md5&#8243;}) query:</p>
<pre name="code" class="php:nogutter">
protected function write() {
		$success = false;
		$grid = File::getGridFS();
		$this-&gt;fileName = $this-&gt;request-&gt;data['Filedata']['name'];
		$md5 = md5_file($this-&gt;request-&gt;data['Filedata']['tmp_name']);
		$file = File::first(array('conditions' =&gt; array('md5' =&gt; $md5)));
		if ($file) {
			$success = true;
			$this-&gt;id = (string) $file-&gt;_id;
		} else {
			$this-&gt;id = (string) $grid-&gt;storeUpload('Filedata', $this-&gt;fileName);
			if ($this-&gt;id) {
				$success = true;
			}
		}
		return $success;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=352</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MongoNYC, Go MongoDB Go!</title>
		<link>http://www.lightcubesolutions.com/blog/?p=327</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=327#comments</comments>
		<pubDate>Thu, 03 Jun 2010 02:23:03 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=327</guid>
		<description><![CDATA[Congrats 10gen on a great event. It was a huge cheer for MongoDB. During and after the event you can see the strong acceptance of Mongo from the NYC tech community. There are several big names and budding start-ups that have already jumped right in with MongoDB and I don&#8217;t see this trend letting up [...]]]></description>
			<content:encoded><![CDATA[<p>Congrats 10gen on a great event. It was a huge cheer for MongoDB.</p>
<p>During and after the event you can see the strong acceptance of Mongo from the NYC tech community. There are several big names and budding start-ups that have already jumped right in with MongoDB and I don&#8217;t see this trend letting up anytime soon.</p>
<p>So why the blog? I gave the talk on MongoDB and PHP Development. Yes, it&#8217;s an exciting topic! Don&#8217;t you click away and give LightCube a high bounce rate.</p>
<p>Looking back, I took a real cursory path on both topics. That&#8217;s not a bad thing but I feel its time to dig a little deeper. If given the opportunity to speak again I&#8217;ll probably present more complex examples of how I and others have changed the &#8220;M&#8221; in LAMP to MongoDB. If you haven&#8217;t already clicked play jump to slide 23 and about 10:20 in the video for the &#8220;juicy&#8221; part. That&#8217;s where I talk about creating a simple blog with the RAD <a href="http://lithify.me" target="_blank">PHP Framework Lithium</a> and <a href="http://www.mongodb.org" target="_blank">MongoDB</a>. Otherwise, don&#8217;t miss my Yankee Stadium reference and the Magento EAV whack in the first few slides.</p>
<p style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="306" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://blip.tv/play/AYHjn30C" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="306" src="http://blip.tv/play/AYHjn30C" allowfullscreen="true"></embed></object></p>
<div id="__ss_4217379" style="width: 425px;">
<p><strong><a title="Mongo NYC PHP Development " href="http://www.slideshare.net/fhagard/mongo-nyc-php-development">Mongo NYC PHP Development</a></strong></p>
</div>
<p style="text-align: center;"><object id="__sse4217379" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mongonycphpdevelopmentfitzagard-100521210032-phpapp02&amp;stripped_title=mongo-nyc-php-development" /><param name="name" value="__sse4217379" /><param name="allowfullscreen" value="true" /><embed id="__sse4217379" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mongonycphpdevelopmentfitzagard-100521210032-phpapp02&amp;stripped_title=mongo-nyc-php-development" name="__sse4217379" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p style="text-align: left;">If you wanted video of the whole event go here &#8211; <a href="http://mongodb.blip.tv/" target="_blank">http://mongodb.blip.tv/</a></p>
<p style="text-align: center;">
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=327</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LightCube Solutions and MongoNYC</title>
		<link>http://www.lightcubesolutions.com/blog/?p=313</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=313#comments</comments>
		<pubDate>Fri, 07 May 2010 23:38:24 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Conference]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=313</guid>
		<description><![CDATA[Just a quick note to our readers that LightCube Solutions will be presenting at MongoNYC on May 21. Go ahead, click the big badge above to register. I&#8217;ll be speaking about PHP Development with MongoDB. There have been some really awesome projects launched in the PHP/MongoDB community and I&#8217;m going to do my best to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.10gen.com/event_mongony_10may21" target="_blank"><img class="aligncenter size-full wp-image-314" title="badge-mongonyc-large" src="http://www.lightcubesolutions.com/blog/wp-content/uploads/2010/05/badge-mongonyc-large.png" alt="" width="235" height="237" /></a></p>
<p style="text-align: center;"><strong>Just a quick note to our readers that LightCube Solutions will be presenting at MongoNYC on May 21. </strong></p>
<p style="text-align: center;"><strong>Go ahead, click the big badge above to register.</strong></p>
<p><a href="http://www.10gen.com/event_mongony_10may21" target="_blank"></a>I&#8217;ll be speaking about PHP Development with MongoDB. There have been some really awesome projects launched in the PHP/MongoDB community and I&#8217;m going to do my best to bring those to the fore. If you don&#8217;t believe me <a title="github php mongo projects" href="http://github.com/search?type=Repositories&amp;language=php&amp;q=mongo&amp;repo=&amp;langOverride=&amp;x=21&amp;y=18&amp;start_value=1" target="_blank">check the list on github</a>.</p>
<p>Our friends at <a href="http://www.10gen.com/">10gen</a> were kind enough to extend a 25% discount to our readers. Please feel free to use the code &#8216;lightcube&#8217; during registration. We look forward to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=313</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MongoSF and Beyond</title>
		<link>http://www.lightcubesolutions.com/blog/?p=291</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=291#comments</comments>
		<pubDate>Sun, 02 May 2010 19:15:45 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[mongony]]></category>
		<category><![CDATA[mongosf]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=291</guid>
		<description><![CDATA[It was great attending and presenting at the MongoSF conference held on April 30th in San Francisco &#8211; Thanks 10Gen. Speaking with a few attendees I got the feeling that many are moving forward with Mongo production deployments. I should be a bit more specific with my relative use of the word &#8220;many&#8221;: &#8220;The Many&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>It was great attending and presenting at the MongoSF conference held on April 30th in San Francisco &#8211; <a href="http://www.10gen.com/" target="_blank">Thanks 10Gen</a>.</p>
<p>Speaking with a few attendees I got the feeling that many are moving forward with Mongo production deployments. I should be a bit more specific with my relative use of the word &#8220;many&#8221;:</p>
<p><strong>&#8220;The Many&#8221;</strong> &#8211; Yes, I&#8217;m slightly jealous that the Ruby community was there in full force and vocal.</p>
<p><strong>&#8220;The Other Many&#8221;</strong> &#8211; There were also folks who were jumping right in with Java and Python.</p>
<p><strong>&#8220;The Not So Many&#8221;</strong> &#8211; I&#8217;m not getting the same feeling of enthusiasm from the PHP community.</p>
<p>The PHP community doesn&#8217;t seem as audible with their success/concerns/thoughts of using Mongo. There are developers using it and liking it. But it doesn&#8217;t &#8220;feel&#8221; as accepted yet. Maybe this feeling has some substance to it. According to <a href="http://blog.mongodb.org/post/396693738/mongodb-survey-results" target="_blank">a survey taken back in February 2010</a> the Ruby community dominated by representing 40% of the MongoDB users. We&#8217;re even outnumbered by Python users. Of course, one can question how far reaching this survey was. However, considering the fact that several PHP frameworks have made a concerted effort to work with MongoDB I&#8217;m wondering why I&#8217;m not hearing more about it. I&#8217;m probably not listening in the right circles.</p>
<p>With all that said and MongoSF in the past it&#8217;s time to prepare for <a href="http://www.10gen.com/event_mongony_10may21" target="_blank">MongoNY</a>. I&#8217;m going to ask those aforementioned questions to the PHPers who show up so be ready! During the talk I&#8217;ll also discuss each framework and what it&#8217;s doing with MongoDB. Come to MongoNY and lets have a lively PHP/MongoDB discussion. <strong>You can use the discount code &#8220;lightcube&#8221; at checkout for a 25% discount. </strong></p>
<p>In the meantime, here are my slides from the MongoSF presentation:</p>
<p style="text-align: center;"><object id="__sse3831127" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mongosfphpdevelopmentfitzagard-100423101933-phpapp01&amp;rel=0&amp;stripped_title=php-development-with-mongodb" /><param name="name" value="__sse3831127" /><param name="allowfullscreen" value="true" /><embed id="__sse3831127" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mongosfphpdevelopmentfitzagard-100423101933-phpapp01&amp;rel=0&amp;stripped_title=php-development-with-mongodb" name="__sse3831127" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p style="text-align: center;"><strong>(Yes, my JSON business card on slide #2 validates!)</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=291</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Removing Files From MongoDB with GridFS</title>
		<link>http://www.lightcubesolutions.com/blog/?p=257</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=257#comments</comments>
		<pubDate>Thu, 08 Apr 2010 13:14:10 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[How-To]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=257</guid>
		<description><![CDATA[You&#8217;ve quickly put together the code to add files to MongoDB. But as any good DBA and Developer knows not everything that goes into your database should stay there. Yes, you already figured out it&#8217;s as simple as $grid-&#62;remove(). Here is something to keep in mind. MongoGridFS::remove won&#8217;t present you with a message if it [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve quickly put together the code to add files to MongoDB. But as any good DBA and Developer knows not everything that goes into your database should stay there.</p>
<p>Yes, you already figured out it&#8217;s as simple as $grid-&gt;remove(). Here is something to keep in mind. <strong>MongoGridFS::remove won&#8217;t present you with a message if it failed</strong>. To ensure that a file was successfully removed use <strong>MongoDB::lastError()</strong>. You&#8217;ll get an array in return that will show something along the lines of:</p>
<pre>Array
(
[err] =&gt;
[n] =&gt; 0
[ok] =&gt; 1
)</pre>
<p>The field to watch is &#8220;ok&#8221;. The value of &#8220;1&#8243; will return if the remove went according to plan. Otherwise you&#8217;ll get &#8220;0&#8243; and it&#8217;s time to check the value for &#8220;err&#8221;. If you&#8217;re wondering about the &#8220;n&#8221; its the number of files that were removed.</p>
<p>In practice your code could look something like this:</p>
<pre name="code" class="php:nogutter">/*
* function remove
* Removes files from Mongo and captures error if failed
* @return mixed
*/
public function remove($criteria)
{
    //Get the GridFS Object
    $grid = $db-&gt;getGridFS();

    //Setup some criteria to search for file
    $id = new MongoID($criteria['_id']);

    //Remove file
    $grid-&gt;remove(array('_id'=&gt;$id), true);

    //Get lastError array
    $errorArray = $db-&gt;lastError();
    if ($errorArray['ok'] == 1 ) {
        $retval = true;
    }else{
        //Send back the error message
        $retval = $errorArray['err'];
    }

    return $retval;
}</pre>
<p>With a few short lines you&#8217;re able to capture the error message and do whatever you like with it. Hopefully this helps keep your fs.files and fs.chunks collections clean.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=257</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adding Metadata to Files in MongoDB/PHP</title>
		<link>http://www.lightcubesolutions.com/blog/?p=228</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=228#comments</comments>
		<pubDate>Tue, 23 Feb 2010 02:37:49 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[How-To]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=228</guid>
		<description><![CDATA[As a quick followup to the last blog, I was asked to demonstrate how we could include some metadata with a file during or after upload. This is a great feature since we can retrieve all the information attached with a document during a query. Including metadata (i.e. comments, dates, votes or WHATEVER ELSE YOU [...]]]></description>
			<content:encoded><![CDATA[<p>As a quick followup to the <a href="http://www.lightcubesolutions.com/blog/?p=209" target="_blank">last blog</a>, I was asked to demonstrate how we could include some metadata with a file during or after upload.</p>
<p>This is a great feature since we can retrieve all the information attached with a document during a query. Including metadata (i.e. comments, dates, votes or WHATEVER ELSE YOU LIKE) is just as easy.</p>
<p>We are going to pick up the ball at the point where you&#8217;ve got all your MongoDB objects ready:</p>
<pre name="code" class="php:nogutter">&lt;?php
$date = new MongoDate();
//Use $set to add metadata to a file
$metaData = array('$set' =&gt; array(“comment”=&gt;”MongoDB is awesome”, “date”=&gt;$date));

//Just setting up search criteria
$criteria = array('_id' =&gt; $id);

//Update the document with the new info
$db-&gt;grid-&gt;update($criteria, $metaData);

?&gt;
</pre>
<p>Did you break a sweat? Probably not.</p>
<p>BTW, I threw in a little extra tidbit there with MongoDate(). It’s a better way of inputting a date into Mongo instead of using PHP date with a bunch of formatting to get it just right.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=228</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MongoDB and PHP &#8211; A Quick Look at GridFS</title>
		<link>http://www.lightcubesolutions.com/blog/?p=209</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=209#comments</comments>
		<pubDate>Sun, 21 Feb 2010 23:33:07 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[How-To]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=209</guid>
		<description><![CDATA[I&#8217;ve been tweeting quite a bit about MongoDB over the past few weeks and its time to blog. About 2 months ago we decided to install and mess around with MongoDB. We went from messing around to serious adoption about 2 weeks ago when we realized the power of working with it and PHP. It [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been tweeting quite a bit about MongoDB over the past few weeks and its time to blog.</p>
<p>About 2 months ago we decided to install and mess around with MongoDB. We went from messing around to serious adoption about 2 weeks ago when we realized the power of working with it and PHP. It was Mitch Pirtle of <a href="http://www.spacemonkeylabs.com" target="_blank">www.spacemonkeylabs.com</a> that first pointed us in this direction. Mitch was very enthusiastic about Mongo as he explained the great potential. Yet, it was only until I added an array of data from PHP into Mongo that my eyes started to open up.</p>
<p>Go ahead, open another tab in your browser (KEEPING THIS ONE OPEN) and <a href="http://www.google.com/#hl=en&amp;source=hp&amp;q=MongoDB" target="_blank">Google MongoDB</a> if you haven&#8217;t already (I made it easy providing the link). You&#8217;ll find sufficient documentation to give you the warm and fuzzy that <a href="http://www.10gen.com/" target="_blank">10gen</a> isn&#8217;t messing around. They are in the database game for the long haul.</p>
<p>During our play with MongoDB we realized how true the term NoSQL is. For all you SQL grease monkeys out there it&#8217;s liberating. No Joins, No Select, just plain NoSQL.</p>
<p>As an example, let&#8217;s start off with putting uploaded files &#8220;directly&#8221; into MongoDB via GridFS (the storage specification for handling large files). Here is how simple it is:</p>
<p>First, we are going to assume you already have the code in place to handle the upload itself. We first tested this using <a href="http://swfupload.org/" target="_blank">SWFUpload</a> which provides quite a bit of flexibility if you like to control how your page looks during upload. From a PHP perspective, the uploaded file will be accessible via the predefined variable $_FILES.</p>
<p>Here is what you have to do to get the upload into MongoDB:</p>
<pre name="code" class="php:nogutter">&lt;?php

$m = new Mongo(); //connect
$db = $m-&gt;selectDB("example"); //select Mongo Database

$grid = $db-&gt;getGridFS(); //use GridFS class for handling files

$name = $_FILES['Filedata']['name']; //Optional - capture the name of the uploaded file
$id = $grid-&gt;storeUpload('Filedata',$name) //load file into MongoDB

?&gt;
</pre>
<p>Yep, that was it. One thing that took me a &#8220;second&#8221; to realize is that you actually pass the literal name of the file_post_name (in the example &#8216;Filedata&#8217;) to MongoDB. It does all the heavy lifting of getting the data from the system and storing it. Also, take note that you get an $id back which is the MongoID that acts as the &#8220;primary key&#8221;. That makes it easy for you to reference the file right away if you need to.</p>
<p>So that&#8217;s a rather quick look and tip for MongoDB. Stay tuned  as we continue to put out our MongoDB tricks and tips for PHP. We&#8217;re in it for the long haul too.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=209</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>It&#8217;s February Already?</title>
		<link>http://www.lightcubesolutions.com/blog/?p=183</link>
		<comments>http://www.lightcubesolutions.com/blog/?p=183#comments</comments>
		<pubDate>Sat, 06 Feb 2010 04:03:57 +0000</pubDate>
		<dc:creator>fhagard</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.lightcubesolutions.com/blog/?p=183</guid>
		<description><![CDATA[Where did January go? Where did 2009 go? Our last blog post was in December? Wow, time is flying by. The good news is we&#8217;ve been quite busy here at LightCube. The bad news is we are breaking the rule of blogging regularly (sorry). Looking back, the past two years has brought its challenges and [...]]]></description>
			<content:encoded><![CDATA[<p><em>Where did January go?</em></p>
<p><em>Where did 2009 go?</em></p>
<p><em>Our last blog post was in December?</em></p>
<p>Wow, time is flying by. The good news is we&#8217;ve been quite busy here at LightCube. The bad news is we are breaking the rule of blogging regularly (sorry).</p>
<p>Looking back, the past two years has brought its challenges and lessons. But we are now looking forward and gearing up for what&#8217;s in store. Speaking of which, where is what we&#8217;ve been up to:</p>
<p><a href="http://www.lightcubesolutions.com/blog/wp-content/uploads/2010/02/tienda.png"><img class="alignleft size-full wp-image-192" title="tienda" src="http://www.lightcubesolutions.com/blog/wp-content/uploads/2010/02/tienda.png" alt="" width="124" height="48" /></a>Tienda! &#8211; Who says the internet doesn&#8217;t need another eCommerce tool? If you check with the Joomla community you&#8217;ll quickly see there is a massive need. We&#8217;ve been working with <a title="Dioscouri" href="http://www.dioscouri.com/" target="_blank">Dioscouri</a> to bring the first native eCommerce application to Joomla! The really exciting news is that <a title="Tienda 0.2.0" href="http://www.dioscouri.com/index.php?option=com_content&amp;view=section&amp;layout=blog&amp;id=10&amp;Itemid=209" target="_blank">Tienda v0.2.0</a> (Alpha) is available.</p>
<p><a href="http://www.lightcubesolutions.com/blog/wp-content/uploads/2010/02/logo-mongodb-onwhite-e1265428137974.png"><img class="alignleft size-medium wp-image-194" title="logo-mongodb-onwhite" src="http://www.lightcubesolutions.com/blog/wp-content/uploads/2010/02/logo-mongodb-onwhite-300x100.png" alt="" width="125" height="40" /></a><a title="MongoDB" href="http://www.mongodb.org/display/DOCS/Home" target="_blank"></a></p>
<p><a title="MongoDB" href="http://www.mongodb.org/display/DOCS/Home" target="_blank">MongoDB</a> &#8211; For a SQL Grease Monkey like myself this is a huge redirection. Don&#8217;t worry, we&#8217;re not abandoning our traditional LAMP stack just yet. It&#8217;s not so much about leaving MySQL as much as it is about being liberated to use something else. We&#8217;re already working on a few pet projects to use MongoDB for our core ACL and automatic MediaRSS feed generating.</p>
<p>WebEDI &#8211; What is <a title="Wikipedia EDI Article" href="http://en.wikipedia.org/wiki/Electronic_Data_Interchange" target="_blank">EDI</a> you ask? It&#8217;s a LONG story. But I can tell you this much,  it has been around before the internet and isn&#8217;t going away anytime soon. We are helping to enhance the EDI back office systems of companies that are warming up to web services and XML.</p>
<p>I did say a quick summary didn&#8217;t I? Although tomorrow isn&#8217;t promised to anyone this year is going to be a busy one. We&#8217;ll keep you posted (hopefully in increments shorter than a month).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lightcubesolutions.com/blog/?feed=rss2&amp;p=183</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
