Friday, May 27, 2016

My Journey with MongoDB

In 2011, I'd been a SQL Server guy (development, DBA and warehousing) for quite some time and I never meant to set out to find a new data store. I was working as a DBA at the time, and we were asked to look into this new data storage technology called Cassandra. At the time you had to build things manually and that was outside of what we did, so we never went anywhere with it.

That quick look however got me looking at other database technologies and and that's when I came across MongoDB. This was around the time that version 1.8 came out. I started looking at MongoDB to see what it was all about. I was still stuck in my relational ways, but thought that there was something to this new tech. I went out and bought Kristina Chodorow's MongoDB: The Definitive Guide and Kyle Banker's MongoDB in Action. After reading through these books and playing around my mind started grasping the concepts and was beginning to break free from the confines of the relational world. I started seeing how denormalizing (storing duplicate data in multiple documents) the data into a single document made sense. You could store all the data that should be together and wouldn't have to pay the overhead of joining tables. The more I worked with MongoDB the more it made sense.

Shortly after this, another team in the company was looking at using MongoDB as a backend data store for a project they were working on. The project was to replicate something similar to Google Analytics that we could put on our client's web sites and custom build tracking for them. Since I wanted to get some practical experience with the technology, I moved over to that team and spent a month building out a prototype of the system. Unfortunately the developer that I was working with on the project had decided to go a different direction and the project was scrapped.

This had given me a taste of what MongoDB could do, and I kept working with MongoDB in a personal capacity for a while. At the end of 2011, MongoDB University released their first two courses and I decided to take M201. I wasn't sure how involved the courses were so I only wanted to take one at a time. After I passed that course, I took M101 (later renamed to M101P) and I passed that course as well. After I completed M101, I reached out to Andrew Erlichson about becoming a TA for the courses. I was brought on and spent the next two years supporting the M101J, M101JS and M201 courses at various times. The education team was a pleasure to work with and I will always be grateful to them for allowing me to spend that length of time with them. I also learned a lot from the students during that time. For my work with the team, they honored me by giving me the first MongoDB DBA certification back in 2013.

After two years of helping out on the education team I made the hard choice to step away from my role as a TA since my available free time shrunk and I felt that I wasn't giving the students (and the other TAs) the time and attention that was required. I however wasn't done with MongoDB by any means.

About four months later, I was contacted to join the MongoDB Advocacy Hub and have been enjoying helping out with promoting MongoDB in various ways. It's been great working the community team members and getting to know them. I'm slowly getting into blogging now with the encouragement from the marketing and community team members at MongoDB. With my work here I have been honored by being chosen as the MongoDB Giant of the Month for January 2016, and most recently was selected to join the MongoDB Masters Program for 2016.

Most recently I have taken over as the Denver/Boulder MongoDB Meet Up Group organizer. This has been a big change for me as I'm more comfortable being behind the scenes, then organizing them and being front and center. It has only been a few months since starting this leg of my journey, but I've met some wonderful people and glad to see the local community coming out and learning from our speakers. If you're ever in the area stop on in.

My journey has taken me along different paths with MongoDB and I'm glad to have traveled them all. I'm not sure where the adventure will take me in the future, but I know that I'll meet great people along the way and will never be alone.

It's interesting looking back, to realize that I came across the product by chance. Had we not taken a look at Cassandra back then, who knows if I would have payed attention to MongoDB. I have stayed with it for five years now because of the value and ease of working with the product, and the great staff and community the company has assembled and built.

Wednesday, May 25, 2016

Five Easy Ways to Get Started With MongoDB

1. Download the community edition and play
The community edition is available freely and there are installers for all major operating systems (Linux, OS X, Windows and Solaris). This makes getting a system up and running quickly very easy to do. It should only take a few minutes to install MongoDB and you're ready to start playing and learning how to work with the quickest growing and most popular NoSQL database.

2. Work through the getting started guide
MongoDB provides a getting started guide for the `mongo` shell, Python, Java, C++, NodeJS and C#. Working through the examples provided there will get you up and going with the basics in no time. From there you'll be ready to move on to more involved examples and walkthroughs that you might find on the internet.

3. Take a course at MongoDB University
MongoDB has the best set of online learning courses out there. You can learn to code against MongoDB in four different languages currently: Python, Java, NodeJS and .NET. There are two different DBA courses covering basic and advanced topics. There is an advanced level course on cluster management. These courses are seven weeks long, with the exception of the cluster management course which is only two weeks. Having been through most these courses I wholeheartedly recommend them. They are well done and the forums are moderated by a great group of online TAs with deep knowledge in the respective course topics.

4. Read Kristina Chodorow's MongoDB: The Definitive Guide
If you only read one book on MongoDB, this is the book to read. Even though the second edition came out in early 2013 and covers MongoDB 2.6, you will still learn a lot by reading it. This is also a must read for anyone who's looking at studying for the certification exams. Rumor has it that a third edition is in the works, but I've not seen anything definitive on that. Once it comes out, I'll definitely be grabbing a copy as quickly as I can.

5. Join your local MongoDB user group
Perhaps the funnest way to learn MongoDB and how to go from the basics to more advanced topics is to join your local MongoDB User Group (MUG). These groups are frequented by very passionate MongoDB users and you'll find talks ranging from beginning to advanced topics. Equally important to the talks are the conversations you'll have and the friendships you'll make with your fellow community members.

Note that MongoDB makes it easy for anyone to get started with their database and they have built a great community to help get answers to any questions new users might have. Very few products have that type of community support and buy in. In addition to the community, the employees that I have met and worked with are some of the nicest people around. They've always had time to help me through problems in a way that I didn't seem rushed to get out of their hair. If MongoDB fits your use case definitely install it and put it through its paces and you might be surprised at how easy and quick it is to get things running.

Monday, February 15, 2016

Getting distinct values from MongoDB

MongoDB has a function called distinct that allows you get a list of all the distinct values in the given collection for a single key. Let's say that you wanted to see all of the distinct values for the key OffenseTeam in a collection called pbp_2015. You would use the following statement:

db.pbp_2015.distinct("OffenseTeam")

The result of this statement is an array with each distinct value for the given key. Your results would look something like this:

[
  "",
  "WAS",
  "BUF",
  "CLE",
  "NYJ",
  ⋮
  "JAC",
  "MIA",
  "SEA",
  "GB",
  "IND",
  "STL"
]

Note: results truncated for brevity.

You can also provide a query to this function to view the distinct values on a subset of the data.
db.pbp_2015.distinct("OffenseTeam", {"PlayType": "FIELD GOAL", "Quarter": 4, "Down": {"$ne": 4}})

The above shows us which teams attempted to kick a field goal in the fourth quarter of a game, even if it wasn't their final down. The results show that there were a total of 9 teams that did this in the 2015 football year.

[
  "JAC",
  "BAL",
  "NO",
  "TB",
  "CHI",
  "KC",
  "OAK",
  "NYJ",
  "MIN"
]

While this is great for getting distinct values for a single field, what do you do if you need to get a list of the distinct combination of two or more fields?

One option is to use the aggregation framework to get this information.

The following is an example:

db.pbp_2015.aggregate(
    [
        {
            "$match": {
                "PlayType": "FIELD GOAL",
                "Down": {"$ne": 4},
                "Quarter": 4
            }
        },
        {
            "$project": {
                "OffenseTeam": 1,
                "DefenseTeam": 1,
                "_id": 0
            }
        },
        {
            "$group": {
                "_id": {
                    "OffenseTeam": "$OffenseTeam",
                    "DefenseTeam": "$DefenseTeam"
                }
            }
        },
        {
            "$sort": {
                "_id": 1
            }
        }
    ]
)

The above aggregation is similar to the prior distinct command, you can see that we have the same match criteria ({"PlayType": "FIELD GOAL", "Down": {"$ne": 4}, "Quarter": 4}). This time however we want to see not only the offensive team, but the defensive team as well. Since those are the only fields we care about, we will $project them out. Next we will group on OffsenseTeam and DefenseTeam by combining them into compound _id key to get our list. Finally we'll sort documents on _id to make it easier to read the data.

The results look like the following:

{
  "waitedMS": NumberLong("0"),
  "result": [
    {"_id": {"OffenseTeam": "BAL", "DefenseTeam": "PIT"}},
    {"_id": {"OffenseTeam": "BAL", "DefenseTeam": "SD"}},
    {"_id": {"OffenseTeam": "BAL", "DefenseTeam": "STL"}},
    {"_id": {"OffenseTeam": "CHI", "DefenseTeam": "DET"}},
    {"_id": {"OffenseTeam": "CHI", "DefenseTeam": "OAK"}},
    {"_id": {"OffenseTeam": "JAC", "DefenseTeam": "BAL"}},
    {"_id": {"OffenseTeam": "JAC", "DefenseTeam": "IND"}},
    {"_id": {"OffenseTeam": "KC", "DefenseTeam": "CHI"}},
    {"_id": {"OffenseTeam": "MIN", "DefenseTeam": "CHI"}},
    {"_id": {"OffenseTeam": "NO", "DefenseTeam": "ATL"}},
    {"_id": {"OffenseTeam": "NO", "DefenseTeam": "DAL"}},
    {"_id": {"OffenseTeam": "NO", "DefenseTeam": "NYG"}},
    {"_id": {"OffenseTeam": "NYJ", "DefenseTeam": "NE"}},
    {"_id": {"OffenseTeam": "OAK", "DefenseTeam": "DEN"}},
    {"_id": {"OffenseTeam": "TB", "DefenseTeam": "HOU"}}
  ],
  "ok": 1
}

Here you can see that while there were 9 teams that kicked a field goal in the fourth quarter even though they weren't facing a fourth down at the time, several teams did this in multiple games (BAL, CHI, JAC, and NO).

As you can see, you can use the aggregation framework to get the distinct values over multiple keys. This information can be used for a variety of purposes such as the case we used it above. Another use would be to use this to determine the selectivity of keys in an index.

Data for the samples can be found here. The data was cleaned up using code from this MongoDB blog post.

Sunday, June 29, 2014

Book Review: Moodle Course Design Best Practices


Recently I was given a reviewer's copy of Moodle Course Design Best Practices from the publisher Packt Pub. The fact that I was given a copy of the book in exchange for a written review has in no way influenced my rating of the book.

Moodle Course Design Best Practices by Susan Smith Nash and Michelle Moore was a fairly quick read that gives a high level introduction on how to set up courses for a few different situations using the Moodle platform.

The first four chapters give guidelines about using Moodle, how to plan and organize your course and finally some best practices in content delivery. These cover topics such as accessibility (offering your content in different formats so those with disabilities can partake in the course), how the platform is laid out, etc.

The next four chapters talk about different learning situations: Independent Study, Teacher-Student interactive courses, Project Based and Online Communities. Each of these chapters talk about the different areas you should include while setting your course up. Obviously the authors can only discuss this at a high level as each course will be different and there will be different requirements.

Overall I thought this was a good book and I thought that the authors met the goal they set out to reach with this book. I wish the authors would have been more consistent with their screenshot usage when illustrating topics. If you want to get an overview of Moodle and get some ideas of how to set up your course with it, this book should help.

For those who like to see actual ratings, I give the book a 4 out of 5 stars.

Sunday, April 13, 2014

Book Review: Getting Started with MariaDB


Recently I was given a reviewer's copy of Getting Started with MariaDB from the publisher Packt Pub. The fact that I was given a copy of the book in exchange for a written review has in no way influenced my rating of the book.

Getting Started with MariaDB by Daniel Bartholomew is a quick introduction to MariaDB. At 100 pages in total (including front and back matter), it obviously cannot go deep in depth about things and must refer you out to the official documentation.

I liked the fact that the author took to the time to walk through examples of setting MariaDB up on Windows, Mac and Linux (sections for Debian based, Red Hat based and general). Chapter 5 is the most useful chapter as it is where you get to see working examples of using MariaDB.

While the book is a good introduction I felt that some things were mentioned that someone new to MariaDB wouldn't need to know. Things like the configuration file (my.ini/my.cnf) are mentioned but the author didn't talk about even the basic entries you might want to put in there. He also has a couple pages talking about the need for security at all levels (internet, intranet, building and server) which while is true, I didn't think that it warranted the mention in an introductory book. And sadly enough this is all mentioned before you learn how to perform basic CRUD operations. :(

One other thing that I found interesting is there is only the briefest mentions of indexing which I feel is a more important topic to a beginner than security and maintenance. Granted that in such a short book you can't put everything in, but indexing is a very important topic and is something someone new to databases needs to know about.

Overall this book should come in handy for someone new to MariaDB, and databases in general, that want to learn the very basics of this database server. However if you have any knowledge of databases already (especially MySQL which MariaDB is based off of), you will want to pass on this book.

For those who like to see actual ratings, I give the book a 3 out of 5 stars.

Saturday, April 05, 2014

MongoDB Aggregation for Justin John Mathews - Part 2

Recently on LinkedIn (and as a follow up to a previous post, Justin John Mathews asked a question about being able to return data in a certain format. The input and output records are below. Input
db.users.insert({ courseId: 1, stDt: new Date(2014, 01, 01), endDt: new Date(2014, 01, 20), active: false });
db.users.insert({ courseId: 1, stDt: new Date(2014, 01, 25), endDt: new Date(2014, 02, 10), active: false });
db.users.insert({ courseId: 1, stDt: new Date(2014, 02, 25), endDt: new Date(2014, 03, 10), active: true });
db.users.insert({ courseId: 1, stDt: new Date(2014, 02, 28), endDt: new Date(2014, 06, 10), active: true });
db.users.insert({ courseId: 1, stDt: new Date(2014, 02, 25), endDt: new Date(2014, 02, 30), active: false });
db.users.insert({ courseId: 1, stDt: new Date(2014, 05, 25), endDt: new Date(2014, 10, 30), active: false });
db.users.insert({ courseId: 1, stDt: new Date(2013, 10, 01), endDt: new Date(2014, 08, 10), active: true });
db.users.insert({ courseId: 1, stDt: new Date(2014, 09, 01), endDt: new Date(2014, 11, 30), active: false });
Output (this is my interpretation as the format he gave was not a valid document)
{
    "result" : {
        "past" : [
            { "endDt" : ISODate("2014-02-20T07:00:00Z"), "active" : false },
            { "endDt" : ISODate("2014-03-10T06:00:00Z"), "active" : false },
            { "endDt" : ISODate("2014-03-30T06:00:00Z"), "active" : false }
        ],
        "current" : [
            { "endDt" : ISODate("2014-04-10T06:00:00Z"), "active" : true },
            { "endDt" : ISODate("2014-07-10T06:00:00Z"), "active" : true },
            { "endDt" : ISODate("2014-09-10T06:00:00Z"), "active" : true }
        ],
        "upcoming": [
            { "endDt" : ISODate("2014-11-30T07:00:00Z"), "active" : false },
            { "endDt" : ISODate("2014-12-30T07:00:00Z"), "active" : false }
        ]
    }
}

As you can see the dates are broken up into three different categories of past, current and upcoming. After talking with Justin, he would like to see the stDt value as well and he doesn't need the active field any longer. Each category is sorted by the endDt. A course is past if the endDt is less than the current date. It is active if the stDt is less than the current date and the endDt is greater than the current date. It is upcoming if the stDt is greater than the current date.

This is the code that I came up with. It does most of what he's looking for, but no matter what I did, I couldn't get the final grouping to display in the sorted order he was looking for in all categories. I'm sure I'm missing something simple, but when printing out the sorted list before the final grouping everything looks fine, but for some reason it's not getting added to the array in the order that I would imagine it should have been.

db.users.aggregate([
    {
        "$project": {
            "range": {
                "stDt": "$stDt",
                "endDt": "$endDt"
            },
            "_id": 0
        }
    },
    {
        "$group": {
            "_id": null,
            "past": {
                "$addToSet": {
                    "$cond": [
                        {"$lt": ["$range.endDt", new Date()]},
                        "$range",
                        null
                    ]
                }
            },
            "current": {
                "$addToSet": {
                    "$cond": [
                        {
                            "$and": [
                                {"$gt": ["$range.endDt", new Date()]},
                                {"$lt": ["$range.stDt", new Date()]},
                            ]
                        },
                        "$range",
                        null
                    ]
                }
            },
            "upcoming": {
                "$addToSet": {
                    "$cond": [
                        {"$gt": ["$range.stDt", new Date()]},
                        "$range",
                        null
                    ]
                }
            }
        }
    },
    {"$unwind": "$past"},
    {"$unwind": "$current"},
    {"$unwind": "$upcoming"},
    {
        "$match": {
            "past": {"$ne": null},
            "current": {"$ne": null},
            "upcoming": {"$ne": null}
        }
    },
    {
        "$sort": {
            "past.endDt": -1,
            "current.endDt": -1,
            "upcoming.endDt": -1
        }
    },
    {
        "$group": {
            "_id": null,
            "past": {"$addToSet": "$past"},
            "current": {"$addToSet": "$current"},
            "upcoming": {"$addToSet": "$upcoming"}
        }
    },
    {
        "$project": {
            "past": 1,
            "current": 1,
            "upcoming": 1,
            "_id": 0
        }
    },
])
And here is the output you get in MongoDB 2.2.x or 2.4.x.
{
    "result" : [
        {
            "past" : [
                {
                    "stDt" : ISODate("2014-02-25T07:00:00Z"),
                    "endDt" : ISODate("2014-03-10T06:00:00Z")
                },
                {
                    "stDt" : ISODate("2014-02-01T07:00:00Z"),
                    "endDt" : ISODate("2014-02-20T07:00:00Z")
                },
                {
                    "stDt" : ISODate("2014-03-25T06:00:00Z"),
                    "endDt" : ISODate("2014-03-30T06:00:00Z")
                }
            ],
            "current" : [
                {
                    "stDt" : ISODate("2014-03-25T06:00:00Z"),
                    "endDt" : ISODate("2014-04-10T06:00:00Z")
                },
                {
                    "stDt" : ISODate("2014-03-28T06:00:00Z"),
                    "endDt" : ISODate("2014-07-10T06:00:00Z")
                },
                {
                    "stDt" : ISODate("2013-11-01T06:00:00Z"),
                    "endDt" : ISODate("2014-09-10T06:00:00Z")
                }
            ],
            "upcoming" : [
                {
                    "stDt" : ISODate("2014-06-25T06:00:00Z"),
                    "endDt" : ISODate("2014-11-30T07:00:00Z")
                },
                {
                    "stDt" : ISODate("2014-10-01T06:00:00Z"),
                    "endDt" : ISODate("2014-12-30T07:00:00Z")
                }
            ]
        }
    ],
    "ok" : 1
}

This works well for the small test set you gave, but it might not be that great for larger datasets. You'll need to test that before putting this code into production. If nothing else this gives you an idea of how you can do things with the aggregation framework.

Tuesday, April 01, 2014

MongoDB Aggregation Query for Justin John Mathews

Recently on LinkedIn, Justin John Mathews asked a question about being able to return data in a certain format. The input and output records are below. Input
db.users.insert({ courseId: 1, stDt: new Date(2014, 01, 01), endDt: new Date(2014, 01, 20), active: false });
db.users.insert({ courseId: 1, stDt: new Date(2014, 01, 25), endDt: new Date(2014, 02, 10), active: false });
db.users.insert({ courseId: 1, stDt: new Date(2014, 02, 25), endDt: new Date(2014, 03, 10), active: true });
db.users.insert({ courseId: 1, stDt: new Date(2014, 02, 28), endDt: new Date(2014, 06, 10), active: true });
db.users.insert({ courseId: 1, stDt: new Date(2014, 02, 25), endDt: new Date(2014, 02, 30), active: false });
db.users.insert({ courseId: 1, stDt: new Date(2014, 05, 25), endDt: new Date(2014, 10, 30), active: false });
db.users.insert({ courseId: 1, stDt: new Date(2013, 10, 01), endDt: new Date(2014, 08, 10), active: true });
db.users.insert({ courseId: 1, stDt: new Date(2014, 09, 01), endDt: new Date(2014, 11, 30), active: false });
Output
{
    "result" : {
        true : [
            { endDt: new Date(2014, 03, 10), active: true },
            { endDt: new Date(2014, 06, 10), active: true },
            { endDt: new Date(2014, 08, 10), active: true },
        ],
        false: [
            { endDt: new Date(2014, 01, 20), active: false },
            { endDt: new Date(2014, 02, 10), active: false },
            { endDt: new Date(2014, 02, 30), active: false },
            { endDt: new Date(2014, 10, 30), active: false },
            { endDt: new Date(2014, 11, 30), active: false }
        ]
    }
}
The code below is one possible solution. I'm not necessarily happy with everything yet, but it does produce the same results as requested, with two small exceptions. First, the code below displays the ISODate instead of the JavaScript date method which I'm assuming is what should have been in the request as you can't return what's shown above. The other small difference is that since I'm using the aggregation framework with MongoDB 2.4.9, the result is a key of result which contains an array of subdocuments as it's value. There were quite a bit of hoops I jumped through to get this solution, and it could probably be cleaned up quite a bit, but I thought I would throw this post together to let him see that it can be done with a single command if you're patient enough to keep tweaking your pipeline. ;)
db.users.aggregate([

    // Project only what we need.
    {
        "$project": {
            "endDt": 1,
            "active": 1,
            "_id": 0
        }
    },

    // Group to true and false buckets. This will give us arrays with null.
    // We'll remove them in a bit.
    {
        "$group": {
            "_id": "$active",
            "true": {
                "$addToSet": {
                    "$cond": [
                        {"$eq": ["$active", true]},
                        "$endDt",
                        null
                    ]
                }
            },
            "false": {
                "$addToSet": {
                    "$cond": [
                        {"$eq": ["$active", false]},
                        "$endDt",
                        null
                    ]
                }
            }
        }
    },

    // We need to unwind our arrays so we can build them back up without the
    // "null" array.
    {"$unwind": "$true"},
    {"$unwind": "$false"},

    // Project out the values. This will give both a true and false key for
    // each item. This builds our arrays up with the proper endDt and
    // active values.
    {
        "$project": {
            "true": {"endDt": "$true", "active": "$_id"}, 
            "false": {"endDt": "$false", "active": "$_id"}
        }
    },

    // Project out a single value to clean up the "issue" a couple steps above.
    {
        "$project": {
            "value": {
                "$cond": [
                    {"$eq": ["$_id", true]},
                    "$true",
                    "$false"
                ]
            }
        }
    },

    // Group things up again to rebuild our arrays.
    // This adds a single "null" entry that will need to be cleaned up.
    {
        "$group": {
            "_id": null,
            "true": {
                "$addToSet": {
                     "$cond": [
                         {"$eq": ["$_id", true]},
                         "$value",
                         null
                     ]
                }
            },
            "false": {
                "$addToSet": {
                    "$cond": [
                        {"$eq": ["$_id", false]},
                        "$value",
                        null
                    ]
                }
            }
        }
    },

    // Unwind our arrays again so we can clean up one more time.
    {"$unwind": "$true"},
    {"$unwind": "$false"},

    // Match only documents where true and false are not null.
    {
        "$match": {
            "true": {"$ne": null},
            "false": {"$ne": null}
        }
    },

    // Sort our items so we can add the to the array in the correct order.
    // I'm not sure why it has to be descending order, but it works.
    {
        "$sort": {
            "true.endDt": -1,
            "false.endDt": -1
        }
    },

    // Group again to build our array.
    {
        "$group": {
            "_id": null,
            "true": {"$addToSet": "$true"},
            "false": {"$addToSet": "$false"}
        }
    },

    // Once again project out just the fields we need
    {
        "$project": {
            "true": 1,
            "false": 1,
            "_id": 0
        }
    }
])
Here are the returned results in MongoDB 2.2.x - 2.4.x:
{
    "result" : [
        {
            "true" : [
                {
                    "endDt" : ISODate("2014-04-10T06:00:00Z"),
                    "active" : true
                },
                {
                    "endDt" : ISODate("2014-07-10T06:00:00Z"),
                    "active" : true
                },
                {
                    "endDt" : ISODate("2014-09-10T06:00:00Z"),
                    "active" : true
                }
            ],
            "false" : [
                {
                    "endDt" : ISODate("2014-02-20T07:00:00Z"),
                    "active" : false
                },
                {
                    "endDt" : ISODate("2014-03-10T06:00:00Z"),
                    "active" : false
                },
                {
                    "endDt" : ISODate("2014-03-30T06:00:00Z"),
                    "active" : false
                },
                {
                    "endDt" : ISODate("2014-11-30T07:00:00Z"),
                    "active" : false
                },
                {
                    "endDt" : ISODate("2014-12-30T07:00:00Z"),
                    "active" : false
                }
            ]
        }
    ],
    "ok" : 1
}
And in the soon to be released version 2.6.0, the results look like the following:
{
    "true" : [
        {
            "endDt" : ISODate("2014-04-10T06:00:00Z"),
            "active" : true
        },
        {
            "endDt" : ISODate("2014-07-10T06:00:00Z"),
            "active" : true
        },
        {
            "endDt" : ISODate("2014-09-10T06:00:00Z"),
            "active" : true
        }
    ],
    "false" : [
        {
            "endDt" : ISODate("2014-02-20T07:00:00Z"),
            "active" : false
        },
        {
            "endDt" : ISODate("2014-03-10T06:00:00Z"),
            "active" : false
        },
        {
            "endDt" : ISODate("2014-03-30T06:00:00Z"),
            "active" : false
        },
        {
            "endDt" : ISODate("2014-11-30T07:00:00Z"),
            "active" : false
        },
        {
            "endDt" : ISODate("2014-12-30T07:00:00Z"),
            "active" : false
        }
    ]
}

Wednesday, March 19, 2014

Packt Publishing celebrates their 2000th title with and exclusive offer


Known for their extensive range of pragmatic IT ebooks, Packt Publishing are celebrating their 2000th book title `Learning Dart’– they want their customers to celebrate too.

To mark this milestone Packt Publishing will launch a ‘Buy One Get One Free’ offer across all eBooks on March 18th – for a limited period only.

Packt is one of the most prolific and fast-growing tech book publishers in the world. Originally focused on open source software, Packt contributes back into the community paying a royalty on relevant books directly to open source projects. These projects have received over $400,000 as part of Packt’s Open Source Royalty Scheme to date.

Their books focus on practicality, recognising that readers are ultimately concerned with getting the job done. Packt’s digitally-focused business model allows them to quickly publish up-to-date books in very specific areas across a range of key categories – web development, game development, big data, application development, and more. Their commitment to providing a comprehensive range of titles has seen Packt publish 1054% more titles in 2013 than in 2006.

Here are some of the best titles across Packt's main categories - but Buy One, Get One Free will apply across all 2000 titles:

Sunday, March 09, 2014

Book Review: Test Driven Development with Mockito


Recently I was given a reviewer's copy of Test Driven Development with Mockito from the publisher Packt Pub. The fact that I was given a copy of the book in exchange for a written review has in no way influenced my rating of the book.

Test Driven Development with Mockito by Sujoy Acharya is a good introduction to Test Driven Development (TDD) and should get a person new to this methodology up to speed quickly. There are just a couple chapters that actually deal with using Mockito though.

Chapters 1 through 3 bring you up to speed on what TDD is and how to apply it. Chapter 1 gives a definition of TDD and what the methodology is all about. Chapter talks about refactoring: when to do it, when not to do it and when to stop. Chapter 3 talks about applying TDD.

Chapters 4 and 5 start covering the different styles of testing: outside in (mainly used for acceptance and regression testing) and inside out (mainly used in development). Chapter 5 talks about what the author calls test doubles which are stubs, mocks, dummies and fakes.

Chapters 6 and 7 are where we're introduced and shown Mockito in action and how to use it in a TDD environment. You learn how to stub, mock and spy objects which allows you to better test the code's logic and not external dependencies (database connections, email, etc.).

Chapter 8 talks about patterns and gives examples of replacing conditional logic with both the command pattern and the strategy pattern.

Finally chapter 9 talks about adding TDD to legacy code that had no tests originally.

There are two appendixes in the book. Appendix A talks about different tools such as Eclipse and JUnit, while Appendix B talks about agile practices.

Overall I thought the author did a good job of meeting the objectives he set out to meet when writing this book. I wasn't crazy with how some of the code examples were inline text and others were screen shots and there were a couple issues with the text. This book would be good for someone new to TDD and Mockito, but probably not helpful for those who have some experience with either.

For those who like to see actual ratings, I give the book a 4 out of 5 stars.

Friday, February 28, 2014

Book Review: BeagleBone Home Automation


Recently I was given a reviewer's copy of BeagleBone Home Automation from the publisher Packt Pub. The fact that I was given a copy of the book in exchange for a written review has in no way influenced my rating of the book.

BeagleBone Home Automation by Juha Lumme didn't live up to what I thought the book should be.

While I liked the book as an overall book on how you can work with the BeagleBone Black, it didn't seem to cover home automation. It does give lots of ideas that you can build out though. Juha also provides a fair amount of python code for running on the server and an Android based Java application as well.

The reason for the low rating is that I was hoping to see how to integrate the BeagleBone system into the house so you could use it to dim/brighten lights or raise/lower shades based on inputs fed into the system, but that was missing.

I did like chapter 6 which walks you through building an Android app to interface with the BeagleBone remotely. Being able to connect and control the BeagleBone when connected via the internet was a nice addition to the book.

If you want a good introduction to using BeagleBone with some accessories, this is a good book. If you want to build a home automation system, this will give you ideas on how to start things out, but doesn't finish the process in my opinion.

For those who like to see actual ratings, I give the book a 3 out of 5 stars.

Book Review: Building a Home Security System with BeagleBone


Recently I was given a reviewer's copy of Building a Home Security System with BeagleBone from the publisher Packt Pub. The fact that I was given a copy of the book in exchange for a written review has in no way influenced my rating of the book.

Building a Home Security System with BeagleBone by Bill Pretty was a fun book to read.

Bill starts out by giving a quick overview of alarm system sensors: passive infrared, glass break and temperature and then walks you through building a simple alarm.

Chapters 3 and 4 walk you through planning how to layout your system, build the hardware and writing some software to control it.

Chapters 3 and 4 walk you through planning how to layout your system, build the hardware and writing some software to control it.

Chapters 5 and 6 take you through testing and automating the system.

In chapters 7 and 8, Bill gives a solution that will allow you to use the built system to also go through an protect your home's computer network.

The book concludes with a chapter that gives ideas on devices that could be added on such as a fingerprint scanner or RFID reads.

Even though I might never actually build my own home security system, it was interesting to see how the BeagleBone can be used to run this type of system.

For those who like to see actual ratings, I give the book a 5 out of 5 stars.

Wednesday, February 19, 2014

Book Review: Getting Started with Beautiful Soup


Getting Started with Beautiful Soup by Vineeth G. Nair is a book that was easy to read and fun to follow along with.

The book basically has four parts to it. The first part covers chapters 1 and 2 where you install Beautiful Soup and learn how to create objects. The second part covers chapters 3, 4 and 5 where you learn about searching through, navigating over and modifying the contents of the object. The third part covers chapters 6 and 7 where you learn about encoding and output formatters. The final part is chapter 8 where you use all the techniques you've learned in the earlier chapters to build a web scraper that gets price information on Packt Pub books from the publisher itself, Amazon and Barnes & Noble.

The book is well written and is recommended to anyone who wants to learn how to work with Beautiful Soup.

For those who like to see actual ratings, I give the book a 5 out of 5 stars.

Saturday, February 15, 2014

Book Review: Learning Cloudera Impala


Recently I was given a reviewer's copy of Learning Cloudera Impala from the publisher Packt Pub. The fact that I was given a copy of the book in exchange for a written review has in no way influenced my rating of the book.

Learning Cloudera Impala by Avkash Chauhan is a book that I wanted to like, but couldn't really get into.

In addition to numerous errors that I noticed, for me the text didn't flow well and it took me longer to read than it should have because of this. I believe that the author knows how to use and implement Impala, but he had wasn't able to convey that to me in a way that I felt I was learning something. The book is also light on examples showing how the technology can be used to accomplish the task at hand.

I know that Impala is a newer technology and more books will come out covering it, until then I think that reading the online documentation is just as good a bet as reading this book.

I unfortunately can't even recommend this book as a reference as there are too many places that the author sends you to the web to learn more about a topic that he has covered at a very high level.

Maybe I missed the point of this book, but too me it falls short.

For those who like to see actual ratings, I give the book a 2 out of 5 stars.

Sunday, February 09, 2014

Book Review: Learning scikit-learn: Machine Learning in Python


Recently I was given a reviewer's copy of Learning scikit-learn: Machine Learning in Python from the publisher Packt Pub. The fact that I was given a copy of the book in exchange for a written review has in no way influenced my rating of the book.

Learning scikit-learn: Machine Learning in Python by Raúl Garreta and Guillermo Moncecchi is a book that gives you a quick introduction to the scikit-learn toolkit. At a total of 118 pages, this book is a quick and easy read. The authors don't go deep into depth behind the mathematics involved in the different machine learning techniques that they discuss, but then that's not the point of the book and could be seen as a plus to some.

I like the fact that they chose to distribute the code via the iPython notebook format so you can run the code inside a browser window (as long as you have the necessary dependencies installed). The authors walk you through installing most of the dependencies, but there are others that are left to the reader to install on their own, and because of that there were a couple of examples that didn't work properly when walking through them for me. This is in no way a problem with the book though and is easily fixed by downloading the missing Python modules.

I enjoyed walking through the examples and felt that the authors accomplished what they set out to do with this book and highly recommend it to those who want to get an introduction to scikit-learn.

Overall this is a great book and I definitely recommend it.

For those who like to see actual ratings, I give the book a 5 out of 5 stars.

Wednesday, January 08, 2014

Video Review: Build a Network Application with Node


Recently I was given a reviewer's copy of Build a Network Application with Node from the publisher Packt Pub. The fact that I was given a copy of the video in exchange for a written review has in no way influenced my rating of the video.

Build a Network Application with Node by Joe Stanco is a great video tutorial to learning the basics of building network applications with Node.js.

The way the video is structured is that there are 11 topics that are broken up into two to five sessions each. These sessions are a few minutes in length so it's easy to sit down and watch them when have a little free time to spare. Mr. Stanco takes you through setting up Node and what modules are through understanding events and the asynchronous nature of Node and using file streams. Next you learn how to write an HTTP server and then using the Connect and Express frameworks to make your life easier. He finishes up by walking through using databases (MongoDB), real-time communication (Socket.IO) and automated testing.

I felt the sessions were short enough to stay focused but long enough to cover the topics in decent depth.

One thing that I didn't like, although this is more my problem and not the videos, is that Mr. Stanco moves quickly between topics and it's hard to see the results he's showing some times. I know you can pause the video, but it would be nice to have a 10 to 15 second period where the results are shown on screen without having to pause the video to see things.

Overall this is a great video lesson and I definitely recommend it.

For those who like to see actual ratings, I give the video a 5 out of 5 stars.