├── .gitignore ├── .travis.yml ├── package.js ├── index.js ├── LICENSE ├── .versions ├── test.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | before_install: 5 | - "curl -L http://git.io/ejPSng | /bin/sh" 6 | env: 7 | - TEST_COMMAND=meteor 8 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | summary: 'Proper MongoDB aggregations support for Meteor', 3 | version: '1.4.4', 4 | git: 'https://github.com/sakulstra/meteor-aggregate', 5 | name: 'sakulstra:aggregate' 6 | }); 7 | 8 | Package.onUse(function(api) { 9 | configurePackage(api); 10 | }); 11 | 12 | Package.onTest(function(api) { 13 | configurePackage(api); 14 | api.use(['tinytest', 'accounts-password', 'random'], ['server']); 15 | 16 | // common before 17 | api.addFiles(['test.js'], ['server']); 18 | }); 19 | 20 | function configurePackage(api) { 21 | api.versionsFrom('METEOR@1'); 22 | api.use(['mongo'], ['server']); 23 | 24 | // common before 25 | api.addFiles(['index.js'], ['server']); 26 | } 27 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | wrapAsync = Meteor.wrapAsync || Meteor._wrapAsync; 2 | 3 | Mongo.Collection.prototype.aggregate = function(pipelines, options) { 4 | let coll; 5 | if (this.rawCollection) { 6 | // >= Meteor 1.0.4 7 | coll = this.rawCollection(); 8 | } else { 9 | // < Meteor 1.0.4 10 | coll = this._getCollection(); 11 | } 12 | if (MongoInternals.NpmModules.mongodb.version[0] === '3') { 13 | const cursor = wrapAsync(coll.aggregate, coll)(pipelines, options); 14 | return wrapAsync(cursor.toArray, cursor)(); 15 | } 16 | if (MongoInternals.NpmModules.mongodb.version[0] === '4'){ 17 | const cursor = coll.aggregate(pipelines, options); 18 | return wrapAsync(cursor.toArray, cursor)(); 19 | } 20 | 21 | return wrapAsync(coll.aggregate.bind(coll))(pipelines, options); 22 | }; 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 MeteorHacks Pvt Ltd (Sri Lanka). 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /.versions: -------------------------------------------------------------------------------- 1 | accounts-base@1.4.2 2 | accounts-password@1.5.1 3 | allow-deny@1.1.0 4 | babel-compiler@7.0.8 5 | babel-runtime@1.2.2 6 | base64@1.0.11 7 | binary-heap@1.0.10 8 | boilerplate-generator@1.4.0 9 | callback-hook@1.1.0 10 | check@1.3.1 11 | ddp@1.4.0 12 | ddp-client@2.3.2 13 | ddp-common@1.4.0 14 | ddp-rate-limiter@1.0.7 15 | ddp-server@2.1.2 16 | diff-sequence@1.1.0 17 | dynamic-import@0.3.0 18 | ecmascript@0.10.8 19 | ecmascript-runtime@0.5.0 20 | ecmascript-runtime-client@0.6.2 21 | ecmascript-runtime-server@0.5.0 22 | ejson@1.1.0 23 | email@1.2.3 24 | geojson-utils@1.0.10 25 | http@1.4.1 26 | id-map@1.1.0 27 | local-test:sakulstra:aggregate@1.4.0 28 | localstorage@1.2.0 29 | logging@1.1.20 30 | meteor@1.8.6 31 | minimongo@1.4.4 32 | modules@0.11.6 33 | modules-runtime@0.9.2 34 | mongo@1.4.7 35 | mongo-dev-server@1.1.0 36 | mongo-id@1.0.7 37 | npm-bcrypt@0.9.3 38 | npm-mongo@2.2.34 39 | ordered-dict@1.1.0 40 | promise@0.10.2 41 | random@1.1.0 42 | rate-limit@1.0.9 43 | reactive-var@1.0.11 44 | reload@1.2.0 45 | retry@1.1.0 46 | routepolicy@1.0.13 47 | sakulstra:aggregate@1.4.0 48 | service-configuration@1.0.11 49 | sha@1.0.9 50 | socket-stream-client@0.1.0 51 | srp@1.0.10 52 | tinytest@1.1.0 53 | tracker@1.1.3 54 | underscore@1.0.10 55 | url@1.2.0 56 | webapp@1.5.0 57 | webapp-hashing@1.0.9 58 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | Tinytest.add('method signature', function(test) { 2 | const coll = new Mongo.Collection(Random.id()); 3 | test.equal(typeof coll.aggregate, 'function'); 4 | }); 5 | 6 | Tinytest.add("let's aggregate", function(test) { 7 | const coll = new Mongo.Collection(Random.id()); 8 | coll.insert({resTime: 20}); 9 | coll.insert({resTime: 40}); 10 | 11 | const result = coll.aggregate([ 12 | {$group: {_id: null, resTime: {$sum: "$resTime"}}} 13 | ]); 14 | 15 | test.equal(result, [{_id: null, resTime: 60}]); 16 | }); 17 | 18 | Tinytest.add("aggregate on Meteor.users", function(test) { 19 | const coll = Meteor.users; 20 | coll.remove({}); 21 | coll.insert({resTime: 20}); 22 | coll.insert({resTime: 40}); 23 | 24 | const result = coll.aggregate([ 25 | {$group: {_id: null, resTime: {$sum: "$resTime"}}} 26 | ]); 27 | 28 | test.equal(result, [{_id: null, resTime: 60}]); 29 | }); 30 | 31 | Tinytest.add("using some options", function(test) { 32 | const coll = new Mongo.Collection(Random.id()); 33 | coll.insert({resTime: 20}); 34 | coll.insert({resTime: 40}); 35 | 36 | const options = {explain: true}; 37 | const result = coll.aggregate([ 38 | {$group: {_id: null, resTime: {$sum: "$resTime"}}} 39 | ], options); 40 | test.equal(typeof result[0], 'object'); 41 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![](https://api.travis-ci.org/meteorhacks/meteor-aggregate.svg)](https://travis-ci.org/meteorhacks/meteor-aggregate) 2 | 3 | # maintained fork of meteorhacks:aggregate 4 | 5 | A simple package to add proper aggregation support for Meteor. This package exposes `.aggregate` method on `Mongo.Collection` instances. 6 | 7 | > this only works on server side and there is no oberserving support or reactivity built in 8 | 9 | ## Usage 10 | 11 | Add to your app with 12 | ``` 13 | meteor add sakulstra:aggregate 14 | ``` 15 | 16 | Then simply use `.aggregate` function like below. 17 | 18 | ```js 19 | var metrics = new Mongo.Collection('metrics'); 20 | var pipeline = [ 21 | {$group: {_id: null, resTime: {$sum: "$resTime"}}} 22 | ]; 23 | var result = metrics.aggregate(pipeline); 24 | ``` 25 | 26 | ### Using Options 27 | 28 | ~~~js 29 | var result = new Mongo.Collection('metrics'); 30 | var metrics = new Mongo.Collection('metrics'); 31 | var pipeline = [ 32 | {$group: {_id: null, resTime: {$sum: "$resTime"}}} 33 | ]; 34 | var result = metrics.aggregate(pipeline, {explain: true}); 35 | console.log("Explain Report:", JSON.stringify(result[0]), null, 2); 36 | ~~~ 37 | 38 | ## Why? 39 | 40 | There are few other aggregation packages out there. All of them written with some complex hacks and there are some easy way to do things. 41 | They also don't work with custom Mongo drivers as well. 42 | 43 | And this package is short and simple. (~20 LOC) 44 | 45 | 46 | ## What the fork?! 47 | meteorhacks/meteor-aggregate seems pretty unmaintained, so let's maintain a fork! 48 | Meteor 1.7 and it's upgrade to mongodriver v3 introduced some breaking changes which will break meteorhacks:meteor-aggregate. 49 | 50 | ## Breaking changes 51 | - `meteorhacks:collection-utils@1.2.0` is no longer a dependency. If you're using meteor <= 1.0.4 you have to add it manually. 52 | --------------------------------------------------------------------------------