Query-like aggregation

As a followup to #1400, here is my take on more Query-like features for aggregation.

I added an Aggregate constructor with chainable methods; an Aggregate is created when calling Model.aggregate (but the previous syntax still works).

```js
// Previous syntax
Model.aggregate(
  { $group: { _id: null, maxAge: { $max: '$age' } } }
, { $project: { _id: 0, maxAge: 1 } }
, function (err, docs) { ... });

// New syntax
Model.aggregate() // instanceof Aggregate
  .group({ _id: null, maxAge: { $max: '$age' } })
  .select("-_id maxAge") // or  .project({ _id: 0, maxAge: 1 })
  .exec(function (err, docs) { ... }) // instanceof Promise

// Arbitrary operators
Model.aggregate()
  .append(
    { $group: { _id: null, maxAge: { $max: '$age' } } }
  , { $project: { _id: 0, maxAge: 1 } }
  ).exec(callback);
```

I created methods for each existing operator: group, project (with a Query-like select alternative), skip, limit, geoNear, group, unwind, match and sort.

Everything has jsdoc and tests (in model.aggregate.test.js and aggregate.test.js) that all pass as of my last commit (https://github.com/njoyard/mongoose/commit/19ce3035b2c9954bf4bea31bd7bde9f024d03842).

Things that might be useful to add:
* Query-like where/in/lt/gt/... methods to create $match operators. Would be nice to find a way to reuse Query code without actually duplicating it.
* Casting aggregated docs to a matching Schema

Thanks for your feedback !