Posted by & filed under MongoDB, PowerShell.

For one of our side projects, we’ve chosen to use a Microsoft’s ASP.NET MVC 3 framework for our Web Front-Ends and 10gen’s MongoDB situated on top of Ubuntu Server. For the domain we’re working in this has suited us nicely in this project.

As the more Ops focused one in the team I’ve been wanting to leverage my PowerShell foo with MongoDB. It’s always great to step out of your comfort zone and try something new. I wanted to get basic CRUD (create, read, update and delete) functionality working and here are the fruits of my labour.

I assume you’ve already played around with MongoDB or some other NoSQL database. If not, jump over to the the MongoDB site and have see for yourself what you may/may not be missing;

MongoDB
http://www.mongodb.org

So lets get started. Firstly download the latest MongoDB C# drivers from;

mongodb / mongo-csharp-driver
https://github.com/mongodb/mongo-csharp-driver/downloads

Extract then out to a directory. I like to keep all my bins together, so my path will be;

c:\mongodb\bin

Now we’ll need to load the Mongo C# assemblies

PowerShell v1.0 – Use Reflection

[Reflection.Assembly]::LoadFile("c:\mongodb\bin\MongoDB.Bson.dll")
[Reflection.Assembly]::LoadFile("c:\mongodb\bin\MongoDB.Driver.dll")

PowerShell v2.0 – Use Add-Type

Add-Type -Path "c:\mongodb\bin\MongoDB.Bson.dll"
Add-Type -Path "c:\mongodb\bin\MongoDB.Driver.dll"

Now that we have our assemblies load we should be able to leverage the MongoDB.Bson and MongoDB.Driver namespaces. I’m going to assume you already have a MongoDB instance running somewhere.

The next step is to create a db connection to our Mongo instance;

$db = [MongoDB.Driver.MongoDatabase]::Create('mongodb://localhost/awesome?safe=true;slaveok=true')

Reference: Connections
http://www.mongodb.org/display/DOCS/Connections

I’m running a local instance on my machine for testing purposes, hence why it’s localhost, no authentication and no other servers replica/config servers have been specified.

If all goes well, you should be able to query your Mongo server as follows;

[MongoDB.Driver.MongoServer]::GetAllServers().BuildInfo

Your output should be similar to the following;

Bits          : 64
GitVersion    : 927beb54fb5ec38ccd0ca5fa712564a0696c9003
SysInfo       : windows sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack='Service Pack 1') BOOST_LIB_VERSION=1_49
Version       : 2.1.2.0
VersionString : 2.1.2

A massive thanks to thanks to Justin for originally blazing the trail with PS and Mongo integration;

Using MongoDB in PowerShell
http://www.justaprogrammer.net/2011/05/14/using-mongodb-in-powershell

We’ll need to define a collection called to store our documents in;

$collection = $db['Users']

Now lets create a basic BSON document to store in our Users collection of Awesome DB;

[MongoDB.Bson.BsonDocument] $doc = @{
    "_id"= [MongoDB.Bson.ObjectId]::GenerateNewId();
    "FirstName"= "Kristof";
    "LastName"= "Kowalski";
    "PhoneNumbers"= [MongoDB.Bson.BsonDocument] @{
        'Home'= '+44-208-1000-1000';
        'Mobile'= '+44-7841-100-100';
    };
};

Lets go ahead and insert the document in the Users collection;

$collection.Insert($doc)

Reference: Inserting
http://www.mongodb.org/display/DOCS/Inserting

To ensure the document was saved you can simply run;

$collection.FindAll()

Reference: Querying
http://www.mongodb.org/display/DOCS/Querying

Your output should be similar to the folowing;

Name                                                                                        Value                                                                                     
----                                                                                        -----                                                                                     
_id                                                                                         4ff44a1e355b9013ecc198f7                                                                  
PhoneNumbers                                                                                {Mobile=+44-7841-100-100, Home=+44-208-1000-1000}                                         
FirstName                                                                                   Kristof                                                                                   
LastName                                                                                    Kowalski                                                                                  

So we’ve got the C and R out of the way, now we want to try the U and the D. Lets work with the above example and add an email address. Since it’s NoSQL, we dont really care about schema changes too much. Well, you do but thats for another post, but this is an uber simple example of the beauty of NoSQL databases.

Lets use the the above document and add an email address field to our user using the $set modifier;

$update = @{'$set' = @{'email'= 'kristof@kowalski.ms'}}
$query = @{"_id"= $doc['_id']}
$collection.Update([MongoDB.Driver.QueryDocument]$query, [MongoDb.Driver.UpdateDocument]$update)

Reference: Updating
http://www.mongodb.org/display/DOCS/Updating

If you perform an $collection.FindAll() you should notice that our user now has an email address of type String associated with it. Simples.

Lets finally perform a delete of our document;

$collection.Remove([MongoDB.Driver.QueryDocument]$query)

If you want to play around with querying, updating and deleting on our collection here’s quick script that will generate some random users and their assocaited phone numbers. There’s no better way to learn then actually getting down and dirty with it.

# Insert 1000 users into the Users collection
$x = 0
while ($x -le 1000)
{
    $firstName = @( "John", "Mike", "Andrew", "Bob", "Stuart", "Aaron", "Abbott", "Abel", "Acelin", "Adon", "Rafi", "Randal", "Randall" ) | Get-Random
    $lastName = @( "Smith", "Jones", "Andrews", "Scully", "Kowalski" ) | Get-Random
    $homeNumber = "+44-208-" + (Get-Random -Count 1 -InputObject (1000..9999)).ToString() + "-" + (Get-Random -Count 1 -InputObject (1000..9999)).ToString()
    $mobileNumber = "+44-7841-" + (Get-Random -Count 1 -InputObject (100..999)).ToString() + "-" + (Get-Random -Count 1 -InputObject (100..999)).ToString()

    [MongoDB.Bson.BsonDocument] $doc = @{
    "_id"= [MongoDB.Bson.ObjectId]::GenerateNewId()
    "FirstName"= "$firstName"
    "LastName"= "$lastName"
    "PhoneNumbers"= [MongoDB.Bson.BsonDocument] @{
        'Home'= $mobileNumber
        'Mobile'= $homeNumber
                }
            }
    Write-Host "Inserting document $x"
    $collUsers.Insert($doc) | Out-Null
    $x++
}

I’ll be posting some more details about using advanced queries and GridFS in the next round of posts, so stay tuned. Give MongoDB a whirl and I’m sure you’ll be pleasantly surprised.

Enjoy,

Kristof

2 Responses to “Working with MongoDB and PowerShell”

  1. Kristof Kowalski

    No probs! Thanks for blazing trail on awesome PS and Mongo integration.

    Reply
  2. John Moses

    Two steps for powershell noobies:
    1. Right click, unblock all the mongodb files
    2. Set unrestricted policy `Set-ExecutionPolicy Unrestricted`

    Reply

Leave a Reply

  • (will not be published)