node.js - mapReduce not calling map nor reduce -


i started working mongodb , having troubles using mapreduce function. reason seems not calling map , reduce functions.

here code:

@getmonthlyreports: (req, res) ->     app_id = req.app.id     start = moment().subtract('years', 1).startof('month').unix()     end = moment().endof('day').unix()     console.log(start)     console.log(end)      map = ->         geotriggers = 0         pushes = 0         console.log("ok")         date = moment(@timestamp).startof('month').unix()         campaign in @campaigns             if campaign.geotriggers?                 geotriggers += campaign.geotriggers             else if campaign.pushes?                 pushes += campaign.pushes          emit date,             geotriggers: geotriggers             pushes: pushes      reduce = (key, values) ->         console.log("ok")         geotriggers = 0         pushes = 0         value in values             geotriggers += value.geotriggers             pushes += value.pushes         geotriggers: geotriggers         pushes: pushes       common.db.collection(req.app.id + "_daily_campaign_reports").mapreduce map, reduce,         query:             timestamp:                 $gte: start                 $lt: end          out:             inline: 1     , (err, results) ->         console.log(results)           responsehelper.returnmessage req, res, 200, results 

i put console.logs , seems map , reduce functions not being called. results undefined.

is there missing?

apart how have commented on reason mapreduce failing due calling library function not exist on server (moment.js), not usage of mapreduce.

while mapreduce has it's uses, simple aggregation case better suited aggregation framework native c++ implementation opposed mapreduce runs inside javascript interpreter. result processing faster.

all need existing unix timestamp values start , end current day of month ( dayofmonth ) in order date math:

db.collection.aggregate([     // match documents using existing start , end values     { "$match": {         "timestamp": { "$gte": start, "$lt": end }     }},      // unwind campaigns array     { "$unwind": "$campaigns" },      // group on start of month value     { "$group": {         "_id": {              "$subtract": [                "$timestamp",                { "$mod": [ "$timestamp", 1000 * 60 * 60 * 24 * dayofmonth ] }             ]         },         "geotriggers": {              "$sum": {                 "$cond": [                    "$campaigns.geotriggers",                    1,                    0                 ]             }         },         "pushes": {              "$sum": {                 "$cond": [                    "$campaigns.pushes",                    1,                    0                 ]             }         },     }} ]) 

if reading code correctly have have each document containing array "campaigns", deal in aggregation framework use $unwind pipeline stage expose each array member it's own document.

the date math done in $group stage _id key changing "timestamp" value equal starting date of month same thing code trying do. it's debatable use null here range selection going result in singular date value, show date math possible.

with "unwound" array elements, process every element "for loop" , conditionally adds values "geotriggers" , "pushes" using $cond operator. again presumes code these fields evaluate boolean true/false evaluation part of $cond

your query condition of course met $match stage @ start of pipeline, using same range query.

that same thing without relying on additional libraries in server side processing , faster well.

see other aggregation framework operators reference.


Comments

Popular posts from this blog

commonjs - How to write a typescript definition file for a node module that exports a function? -

openid - Okta: Failed to get authorization code through API call -

ios - Change Storyboard View using Seague -