Mario Deubler
Mario Deubler

Reputation: 245

Sum Up for each element of Collection.find()

I try to sum up a specific column of my DataPoints Collection which fits to a specific Query.

getClicksTotalCampaign: function () {
    var docs = DataPoints.find({campaign: this._id, influencer: Meteor.userId()});
            var clicks = 0;
            for(var i = 0; i< docs.length; i++) {
                clicks += parseInt(docs[i].clicks);
            }
            return clicks;
    },

I am wrong with the return of DataPoints.find beeing an Array of Objects? The length of it is always null, when i do the query on mongo i get entrys back. @edit Here the Data Schema:

Schemas.DataPoints = new SimpleSchema({

    influencer: {
        type: String,
        label: "Influencer ID"
    },
    advertiser: {
        type: String,
        label: "Advertiser ID"
    },
    campaign: {
        type: String,
        label: "Campaign ID"
    },
    amount: {
        type: Number,
        label: "Amount"
    }    
});

Upvotes: 2

Views: 165

Answers (2)

chridam
chridam

Reputation: 103345

Use the aggregation framework where you can use the $match pipeline operator to filter the collection on the campaign and influencer. The $group pipeline step then groups all the input documents from the filter and applies the accumulator expression $sum to the group to get the total documents count.

Your pipeline would look like this:

var DataPoints = new Mongo.Collection('datapoints');
var pipeline = [
    {
        "$match": {
            "campaign": this._id, 
            "influencer": Meteor.userId()
        }
    },
    {
        "$group": {
            "_id": null,
            "count": {"$sum": "$amount"}
        }
    }
];
var result = DataPoints.aggregate(pipeline).fetch();
var count = result[0].count;

You can add the meteorhacks:aggregate package to implement the aggregation in Meteor:

Add to your app with

meteor add meteorhacks:aggregate

Since this package exposes .aggregate method on Mongo.Collection instances, you can then call the method to get the result array with the document that has the count field. For example

if (Meteor.isServer) {
    var DataPoints = new Mongo.Collection('datapoints');
    Meteor.methods({
        getClicksTotalCampaign: function () {
            var pipeline = [
                {
                    "$match": {
                        "campaign": this._id, 
                        "influencer": Meteor.userId()
                    }
                },                  
                {
                    "$group": {
                        "_id": null,
                        "count": {"$sum": "$amount"}
                    }
                }
            ];
            var result = DataPoints.aggregate(pipeline);
            return result[0].count;
        }
    }); 
}

if (Meteor.isClient) {
    setInterval(function () {
        Meteor.call('getClicksTotalCampaign', updateCounter);
    }, 1000 * 10);

    function updateCounter(err, count) {
        console.log("this is the new count: ", count)
    }
}

Upvotes: 2

Rahul Jain
Rahul Jain

Reputation: 1399

Try this:

var docs = DataPoints.find({campaign: this._id, influencer: Meteor.userId()}).fetch();

Upvotes: 0

Related Questions