Skip to content

Conversation

@njoyard
Copy link
Contributor

@njoyard njoyard commented Mar 28, 2013

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).

// 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 (njoyard@19ce303).

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 !

@aheckmann
Copy link
Collaborator

Sounds good. Will review next week.

On Thu, Mar 28, 2013 at 2:13 AM, Nicolas Joyard [email protected]:

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).

// Previous syntaxModel.aggregate(
{ $group: { _id: null, maxAge: { $max: '$age' } } }, { $project: { _id: 0, maxAge: 1 } }, function (err, docs) { ... });
// New syntaxModel.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 operatorsModel.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 (njoyard/mongoose@19ce303njoyard@19ce303
).

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 !

You can merge this Pull Request by running

git pull https://github.com/njoyard/mongoose master

Or view, comment on, or merge it at:

#1404
Commit Summary

  • Basic Aggregate implementation
  • Added jsdoc to Aggregate
  • Rename #cast to #bind, more descriptive of what it actually does
  • Added #unwind #sort and #match
  • Merge identical methods
  • Add links to doc, add missing tests
  • Fix minor doc issues
  • Plug Aggregate into Model.aggregate()
  • More Model.aggregate() tests

File Changes

Patch Links:

Aaron
@aaronheckmann https://twitter.com/#!/aaronheckmann

@aheckmann
Copy link
Collaborator

merged for 3.7. Thanks!

@aheckmann aheckmann closed this Apr 2, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants