FallenRayne Dev One developer's random thoughts are better than nothing.

29Jan/113

Playing around with MongoDB

So I have been messing around with MongoDB now for about 2 months on a side project that I am working on. I wanted to give a run down on my thoughts about Mongo and the PHP driver for it.

Installation:

The installation of Mongo was relatively simple, mostly because I just installed it on my Ubuntu machine using the Debian package. Got it installed and running in under 20 minutes and had a interface downloaded and in place in about 10 minutes after that. The PHP driver was a simple as running

1
sudo pecl install mongo

and adding

1
extension=mongo.so

to the php.ini file. All in all the process was extremely simple and there were no major hiccups.

Documentation:

The documentation is pretty clear overall. They have some good quick start tutorials and everything is pretty easy to follow. The documentation for the PHP driver is on php.net and just as you would expect PHP documentation, not perfect but most definitely not the worst out there. There have been enough sites that explain usage though I have had some troubles here and there, but I will explain those later.

Ease of Use:

This is where things get fun. Mongo is an extremely fun database to use. The logic of how the documents are constructed just makes so much sense to me as they are essentially just JSON strings. My major passion in web development is JavaScript so this just makes things fun. I am trying to do some great stuff with the queries because I am doing live filtering on the data as the user types. I currently have four different combo boxes and two text fields that the user can type into and automatically filter the content that is displayed. I am able to do this with Mongo's great query capabilities including its Regex search abilities.

The Regex search ability is probably my favorite so far. It has helped me figure out some of the more difficult problems and is extremely fast. I am live filtering on about 12,000 documents or so and checking for values that could be anywhere within a single property of the document and I am getting results back within a second. Regex has also allowed me to get around a missing feature of Mongo that is sorely missed and is probably my only issue with the database; there is no $and operator for the queries. You can do $or, $all, $in, $exists, $ne (not equals), and a bunch of other operators, but no $and. Here is a quick scenario to show why this is missed:

Here are three fake documents. Each one has an id and a tag. The tag just contains a few letters and the user is allowed to enter letters to try and find out if they are in the tag string. The user is expecting only the documents that have ALL of the letters in the tag string to come back, and the letter do not have to be in any particular order.

1
2
3
4
5
6
7
8
9
10
11
12
  {
    _id:'Doc1',
    tag:'ABCDE'
  }
  {
    _id:'Doc2',
    tag:'CBDAE'
  }
  {
    _id:'Doc3',
    tag:'BDAE'
  }

So the user enters in the values of B and C. Doc1 and Doc2 should be returned by not Doc3 because it is missing the letter C. Here is how I would want to create this query:

1
2
3
  $query1 = new MongoRegex('/B/i');
  $query2 = new MongoRegex('/C/i');
  $collection->find('$and'=>array('tag'=>$query1, 'tag'=>$query2));

I am using MongoRegex to create a Regex object that Mongo will understand. Both Regex objects are looking for a single character, and with the $and operator in the query, both regex queries have to return true to return the document. Now this is a very simple example but you can see why it would be useful to have to. Instead I had to resort to pure Regex. Here is the solution I ended up putting in place to handle this exact problem:

1
2
3
4
5
6
  $lettersAry = array();
  foreach($letters as $letter){
    $lettersAry[] = "(?=.*$letter)";
  }
  $regex - '/^'.implode('',$lettersAry).'.*$/i';
  $collection->find('tag'=>new MongoRegex($regex));

That works perfectly for what I need and it puts all of the value checks into one regex object and makes it very easy to pass in as many letters as I want. Is this the perfect solution? Probably not. Does it do the trick? Most definitely.

Summary

Ok, so I didn't have too much to say I guess. I am still working on my app and I don't want to talk about it too much until it is closer to being finished. Hopefully I will be wrapping things up in the new few weeks and I will be able to share more. I will say that MongoDB is very fast, and is very easy to use. I have been able to just focus on my app and less on the database because of this. I haven't had to map out my entire database before I even touched a line of code, instead my database has morphed as I have worked on it. Need to add a new field? Oh well, throw it into the code and it is added! Yay! As a developer working on a side project I really don't want to have to think about the database more than I have too. I just want a place to dump my data and make it easy and fast to retrieve it. Thank you MongoDB for be my data dumping ground.

**Update** Ok, so I have re-written my code to use Kristina's suggestion and I got it working. Not sure why that didn't work for me the first few times I tried but I must have had something all screwy.

Tagged as: 3 Comments
21Jan/110

Not a whole lot

Ok, so this has been a busy week for me at work so I haven't had as much time as I would have liked to work on some stuff. I am currently working on a private project that I hope to have out sometime in the next two months. Progress is slow due to working with code all day and not wanting to work on it much more until midnight, which then keeps me up till 1am and only an hour of work on my personal projects. :\

The new project is pretty cool though. I am using MongoDB, ExtJS, and possibly Symfony to throw it all together. MongoDB is the primary database, I might mixin MySQL at some point but right now MongoDB fits the bill perfectly. ExtJS is going to be the primary frontend with a Sencha Touch tie in for mobile devices and possibly a mobile app. Symfony is going to be mainly used for routing and authentication at this time.

I already have my database populated (which was a pain as I had to scrape a website to get all the data I needed as it is not readily available). I have the initial interface up and running and I am able to do basic queries right now using a ExtJS DataView as the main view with a ExtJS FormPanel controlling the complex filtering. I have to flesh out the filtering more and get that all routed through a solid filter class that I need to write and it should be mostly done.

Once at that point I just have to work on a couple of the other features of the app, clean up the code, and set my Ubuntu box up as my web server. I would use a host for this but it is difficult to find one that gives MongoDB access, and the ones that do normally charge extra. Not to mention that I am already using DreamHost (which ROCKS!) and they are doing pretty good with my other sites that I work on plus this blog. I could always set up a private server with them to use MongoDB but I am cheap at this point and I want to get the app into closed Beta and see how some of my friends like using it before I make any major decisions.

So like I said, hopefully in the next couple of months I will have the closed beta going and I can start making some of the bigger decisions as to where the project will lead. I will give updates on new features I implement and cool things I figure out, but until then I just need to get motivated and get this thing done.

Tagged as: No Comments