Thursday, July 24, 2014

NoSQL - MongoDB; Querying Data

Intro

In Part 1 of the series on NoSQL we were introduced to some of the general concepts behind this movement and how some of the technologies work in a general sense. In Part 2 we setup a MongoDB instance and wrote some C# code to insert data into the DB. Here in the final installment of the series we'll cover getting our data back out of the MongoDB instance.

To the Code!

Let's jump on into some code. Open back up the solution file you created back in Part 2, BlogMongo. If you named your stuff the same I did, you can open up default.aspx and default.aspx.cs also as that's where we'll put our code. I'm adding a new button to the form called btnQuery and giving it a new click event, which I'll leave empty for the moment. Now, do you remember this function from last week?

        private MongoCollection GetMongoCollection()
        {
            var client = new MongoClient("mongodb://localhost");
            var server = client.GetServer();
            var database = server.GetDatabase("BlogMongo");
            return database.GetCollection<Stuff>("stuffses");
        }


This is the function we used last week to connect to our database and our collection (table), using the Mongo C# driver. Now let's pull some data out of it; you'll be surprised just how easy this is:

        
        private void QueryStuff()
        {
            var collection = GetMongoCollection();
            var singleQuery = Query<Stuff>.EQ(e => e.SomeInt, 3);
            var stuff = collection.FindOneAs<Stuff>(singleQuery);
            var serializer = new JavaScriptSerializer();
            Response.Write(serializer.Serialize(stuff));
        }


This method pulls a single document/object out of the database and collection and spits it out in the response. The first line of the method just opens up a connection to the database and retrieves a reference to our collection. The second line creates a Mongo query object (you'll have to add a using statement to MongoDB.Driver.Builders). The query object should return object(s) of type Stuff, and the query shall look for an item with a value of 3 for the property SomeInt. The 3rd line tells the collection to pull back a single item of type Stuff that matches the query we created in the previous line. Line 4 creates a javascript serialization object that we're just using to display some friendly output, and line 5 spits out our serialized JSON object to the browser. Yes that's right, 3 lines of code (which we could easily condense further) pulls a specific object out of the database for us. Nifty! Go ahead and call this new method in the click event of your query button so you can see the output. Just in case you're not coding along with me, here's what the output looks like:

{"Id":"d639cae8-906a-4d7c-ab6d-553319a8a70e","SomeInt":3,"SomeString":"yeah, a string","ListOfStrings":["0","1","2"]}

Ok that was some really cool stuff. Almost as cool as an iceberg hitting you in the face! But how do we create some niftier, more complicated queries? Well as it turns out, the Mongo C# driver supports quite a few LINQ operations for data querying so you can have some real fun here! Let's see another example of querying MongoDB data, this time with LINQ:

        private void QueryStuff()
        {
            var collection = GetMongoCollection();
            var singleQuery = Query<Stuff>.EQ(e => e.SomeInt, 3);
            var stuff = collection.FindOneAs<Stuff>(singleQuery);
            var serializer = new JavaScriptSerializer();
            Response.Write(serializer.Serialize(stuff));
            var linqQuery = from item in collection.AsQueryable<Stuff>()
                            where item.SomeString == "yeah, a string"
                            select item;
            foreach (var item in linqQuery)
                Response.Write(serializer.Serialize(item));
        }



Our new code starts on line 6, beneath the prior junk. Line 6 sets up our LINQ query. I'm assuming you're familiar enough with LINQ to either create LINQ queries or google around to figure out how to make them so I won't go into detail on it, but as you can see this query is meant to select all the items from our collection who have a SomeString property with the value "yeah, a string". (Note: you'll need to add 2 more using statements. MongoDB.Driver.Linq and System.Linq). The foreach below it is just our output generation code. Easy, simple, and powerful, that's the best kind of code there is! Here is the new output (note that it includes the prior line of output too, so there's 1 extra object of type Stuff here):

{"Id":"d639cae8-906a-4d7c-ab6d-553319a8a70e","SomeInt":3,"SomeString":"yeah, a string","ListOfStrings":["0","1","2"]}{"Id":"d639cae8-906a-4d7c-ab6d-553319a8a70e","SomeInt":3,"SomeString":"yeah, a string","ListOfStrings":["0","1","2"]}{"Id":"494be80b-5f1a-48c4-9a15-3c01f89d2216","SomeInt":4,"SomeString":"yeah, a string","ListOfStrings":["0","1","2","3"]}{"Id":"a089f1bd-c33b-43ae-9f25-894e0c5e31c2","SomeInt":5,"SomeString":"yeah, a string","ListOfStrings":["0","1","2","3","4"]}{"Id":"097c8d4f-fff4-4daa-a535-75d38fe87199","SomeInt":3,"SomeString":"yeah, a string","ListOfStrings":["0","1","2"]}

That's pretty much all we're going to cover folks! These are just the basics of querying a MongoDB instance, but this will get you pretty far. Here's the complete code file in case you need it:

using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Linq;
using MongoDB.Driver.Linq;

namespace BlogMongo
{
    public class Stuff
    {
        public Guid Id { get; set; }
        public int SomeInt { get; set; }
        public string SomeString { get; set; }
        public IList<string> ListOfStrings { get; set; }
        public Stuff()
        {
            ListOfStrings = new List<string>();
        }
    }

    public partial class Default : System.Web.UI.Page
    {
        private Stuff GenerateStuff()
        {
            var stuff = new Stuff() { Id = Guid.NewGuid(), SomeInt = new Random().Next(0, 10), SomeString = "yeah, a string" };
            for (int i = 0; i < stuff.SomeInt; i++)
                stuff.ListOfStrings.Add(i.ToString());
            return stuff;
        }

        private MongoCollection GetMongoCollection()
        {
            var client = new MongoClient("mongodb://localhost");
            var server = client.GetServer();
            var database = server.GetDatabase("BlogMongo");
            return database.GetCollection<Stuff>("stuffses");
        }

        private void SaveStuff()
        {
            var stuff = GenerateStuff();
            var collection = GetMongoCollection();
            collection.Save(stuff);
        }

        private void QueryStuff()
        {
            var collection = GetMongoCollection();
            var singleQuery = Query<Stuff>.EQ(e => e.SomeInt, 3);
            var stuff = collection.FindOneAs<Stuff>(singleQuery);
            var serializer = new JavaScriptSerializer();
            Response.Write(serializer.Serialize(stuff));
            var linqQuery = from item in collection.AsQueryable<Stuff>()
                            where item.SomeString == "yeah, a string"
                            select item;
            foreach (var item in linqQuery)
                Response.Write(serializer.Serialize(item));
        }

        protected void btnQuery_Click(object sender, EventArgs e)
        {
            QueryStuff();
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            SaveStuff();
        }

    }
}


What's Next

There are plenty of other ways to query a MongoDB instance. Play around with it and see what you can find, and read the resource links below. The Mongo C# LINQ tutorial and the Mongo C# Driver Getting Started pages are both very handy. This is my last blog on NoSQL (at least for now) though, so we'll be on to a different topic next week. If you want further NoSQL knowledge, then you're on your own buddy!

Resources

MongoDB C# Driver LINQ Tutorial
MongoDB Getting Started With the C# Driver

No comments:

Post a Comment