Aggregation it's pretty neat

So on my latest project I choose to go with MongoDB for a shopcart which heavily relies on parameters.
I've found many advantages of using Mongo on a shopcart, letting me reflect my design in a much efficent way than relational databases.

Aggregation it's kind of a dreaded word when you start looking at mongo documentation, but it's really not that difficult in my experience
for example these are a couple of snippets of code to aggregate orders.

Having the following order structure:

{
    "_id" : ObjectId("548f1b1ec874da273d8b4567"),
    "addresses" : [
        {
            "_id" : ObjectId("548f1b04c874dab0398b4567"),
            "address" : "foobar 123",
            "country" : "AR",
            "state" : "fdsafsda",
            "city" : "fdsafdsa",
            "postal_code" : "3100",
            "type" : "billing",
            "user_id" : NumberLong(3),
            "updated_at" : ISODate("2014-12-15T17:31:48.953Z"),
            "created_at" : ISODate("2014-12-15T17:31:48.953Z")
        },
        {
            "_id" : ObjectId("548f1b16c874dab53b8b4567"),
            "address" : "foboar 432",
            "country" : "AR",
            "state" : "fdsafdsa",
            "city" : "fdsafdsa",
            "postal_code" : "3100",
            "type" : "shipping",
            "user_id" : NumberLong(3),
            "updated_at" : ISODate("2014-12-15T17:32:06.015Z"),
            "created_at" : ISODate("2014-12-15T17:32:06.015Z")
        }
    ],
    "buyer_id" : NumberLong(3),
    "created_at" : ISODate("2014-12-15T17:32:14.616Z"),
    "items" : [
        {
            "rowid" : "c151bea3e12059c20b371ef10d401aea",
            "name" : "Test Product",
            "qty" : NumberLong(1),
            "price" : NumberLong(3200),
            "supplier_id" : NumberLong(2),
            "updated_at" : ISODate("2014-12-15T17:32:14.627Z"),
            "created_at" : ISODate("2014-12-15T17:32:14.627Z"),
            "_id" : ObjectId("548f1b1ec874da273d8b4568")
        }
    ],
    "status" : "pending",
    "total" : NumberLong(3200),
    "updated_at" : ISODate("2014-12-15T17:32:14.616Z")
}

As this is a multi-supplier shopcart, we need to retrieve only the items bought from a specified supplier, this quick query does the job:

db.orders.aggregate({
    "$unwind": "$items"
  },
  {
    "$match": {
      "items.supplier_id": 2
    }
  },
  {
    "$group": {
      "_id": "$_id",
      "items": {
        "$push": "$items"
      },
      "addresses": {
        "$push": "$items"
      },
      "date": {
        "$first": "$created_at"
      },
      "total": {
        "$sum": {
          "$multiply": [
            "$items.price",
            "$items.qty"
          ]
        }
      }
    }
  },
  {
    "$sort": {
      "date": -1
    }
  })

Ok, it's kind of scary, but going step by step is not much harder than your regular SQL sentence, albeit more curly-braces happy for my taste.

First we unwind the items collection inside an order to operate through each of it's element. Then we match only the items we're interested in (those who belong to the current supplier)
we then proceed to group the results in a new order, we define an order id, a collection of items ( we push the selected items into that collection), the addresses of the customers (billing & shipping), the date, and we sum the item prices to get the totals, in the last part of the pipeline we sort the results by date.

Note that the output document is pretty nasty compared to our original order, so we could use $project it to make it nicer, but it's kinda off topic