The following demonstrates how to setup and use MongoDB on Windows with .NET. Most of this info was taken from the quickstart on the MongoDB site.

Installation

  1. Download and unzip the distro from here.
  2. You can install MongoDB as a Windows Service or just run it manually with mongod.exe. The following flags provide MongoDB with the information it needs to run (Use --help for more parameters):

    --logpath [Path]   file to send all output to instead of stdout
    --logappend        append to logpath instead of over-writing
    --dbpath [Path]    directory for datafiles
    --directoryperdb   each database will be stored in a separate directory
     
    --auth             run with security
     

    1. To start manually, run mongod.exe with the above parameters:

      image
    2. To install as a Windows Service run mongod.exe with the above parameters and the following one, then start the service:

      --install    install mongodb service

       image

The Administrative Console

You can interact with MongoDB using the administrative shell, mongo.exe:

image

Securing the Server and Databases

If you want to run in secure mode (With the --auth option above) you will need to setup an administrative user account (More info on this here). If no administrative user is setup yet, you can access the server sans security (Via the admin console mongo.exe) on the same box the server process is running. A special database called "admin" is where you will add the administrative user account with the addUser method. 

image

Notice that after we added the admin user we got an access denied when we tried to enumerate the databases. This is because security is enabled after the first user is added. Once we authenticate with the auth method we can successfully enumerate the databases.

You can also add database specific users the same way you added the administrative user. Simply change to the database and add the user as above. You can specify if the user has read/write or read-only access as the third argument of addUSer:

image

Basic Administrative Operations

The following are some basic operations you can perform in the shell. Most of this info was taken from the shell reference and api reference on the MongoDB site. The shell is a javascript shell so you can use javascript directly in your commands. The DB object represents the current db. The database is created automatically when you first add something to it (Like a user, collection, etc). There is no need to create it explicitly. Database names are case sensitive.

  • db - Displays the current database.
  • db.help() - Displays the methods on the db object.
  • show dbs - Shows a list of all the databases.
  • use [DatabaseName] - Changes the current database. 
  • show collections - Shows all the collections in the database (Or "tables" if your coming from the RDBMS world. They aren't actually relational tables but they are the conceptual counterpart.)
  • db.auth("username", "P@$$w0rd") - Login as a user.
  • show users - Displays the users in a database.
  • db.addUser("username", P@$$w0rd, true) - Adds a user to a database. The last parameter indicates if the user only has read-only access. Despite the "add" in the name, this method also modifies an existing user. So you can run this command against an existing user to change its password or make it read-only.
  • db.system.users.remove({user: "username"}) - Removes a user.

The DBCollection object allows you to work with collections. To access a collection simply type "db" then the collection name (IE db.[CollectionName].insert(...)). If the collection doesn't already exist it will be created automatically when an item is first added to it. There is no need to create it explicitly. Collection names are case sensitive.

  • db.someCollection.find() - Returns the items in the collection. Only displays 25 results, us the it command to continue enumerating.
  • db.someCollection.find().sort({City: -1}) - Returns the items in the collection filtered by criteria and it sorts it ascending or descending (-1 or 1).   
  • db.someCollection.insert({Name: "Kaleb Binkley"}) - Inserts an item into the collection.
  • db.someCollection.find({City: "Grand Junction"}) - Returns the items in the collection filtered by criteria. 
  • db.someCollection.update({AccountId:676}, {$set: {AccountId: 767}}, false, false) - Updates an existing item (Or insert it if it doesn't exist, by setting the third parameter to true). See more here.
  • db.someCollection.save(item) - Shortcut for doing an update with upsert set to true.
  • db.someCollection.remove({AccountId: 767}) - Removes an item from a collection based on the criteria.
  • db.someCollection.drop() - Deletes a collection.

Accessing MongoDB from .NET

To access MongoDB from .NET we're going to use Andrew Theken's norm library. There are a couple of libraries you can use, see here for more info. You can download the NoRM source here, but currently you will have to compile it. May I suggest using nu instead? Here is some info on installing and using nu, I'd highly suggest going this route. Nu is really a slick approach to dependencies that is based on Ruby Gems. The gem name for NoRM is..... norm:

image

Now you can reference this in your project. Andrew has a nice vid here to help get you going. Lets get started by connecting to a MongoDB server:

static void Main(string[] args)
{
    const string connectionString = 
        "mongodb://projecteuleruser:Pa$$w0rd@localhost/ProjectEuler";

    using (var database = Mongo.Create(connectionString))
    { 
    }

    Console.ReadKey();
}

The format of the connection string is "mongodb://username:password@host/database". You can obviously leave out the "username:password@" if your hitting a non secure server. The database object is synonymous to the db object in the administrative console. Now lets start interacting with the database. First we will want to create an entity:

public class User
{
    public User() { Id = Guid.NewGuid(); }

    public Guid Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }

    public override string ToString()
    {
        return string.Format("Username: {0}, Password: {1}, Name: {2}, Email: {3}",
            Username,
            Password,
            Name,
            Email);
    }
}
In the above entity we have a guid "Id" field, which is a required convention. Also it has a parameterless constructor, another requirement. We are generating the guid automatically in the constructor so that new entities are set to go. The overridden ToString() is not important, just for demo purposes. Now we will work with the User collection: 
using (var database = Mongo.Create(connectionString))
{
    var users = database.GetCollection<User>();

    users.Find().ForEach(users.Delete);

    users.Save(new User
                    {
                        Username = "ldebroglie",
                        Email = "louis.debroglie@paris-sorbonne.fr",
                        Name = "Louis De Broglie",
                        Password = "wavemechanics".Hash("ldebroglie")
                    });

    users.Save(new User
                    {
                        Username = "wheisenberg",
                        Email = "werner.heisenberg@uni-muenchen.de",
                        Name = "Werner Heisenberg",
                        Password = "matrixmechanics".Hash("wheisenberg")
                    });

    users.Find().ForEach(Console.WriteLine); 

    Console.WriteLine("Authenticated: {0}", 
                      (users.AsQueryable().
                             Any(u => u.Username == "wheisenberg" && 
                                      u.Password == "wavemechanics".Hash("wheisenberg"))));
}

If the ProjectEuler database or User collection is not already created, they will be automatically created when an action is performed on the User collection. As an aside, the example above uses a couple of extension methods that are not shown. In the above example you can see how we are using the Find method (When we are clearing the collection and enumerating the users) and Linq (When authenticating the user); its up to you how you want to do it. In order to use Linq directly on the collection you will need to make the context switch by calling AsQuerable. The Save method will do an upsert; inserting if new, updating if it exists. Running the application produces the following output (The full code listing can be found here):

image

Going back to our administrative console we can see the new collection and its items:

image

Conclusion

Document databases have a lot of promise, filling a niche that an RDBMS has been traditionally filling (But shouldn't have been). Some other document databases include CouchDB (With a sweet rap video) and RavenDB. Check out the NoRM group page to get involved with that project.