npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mongoose-map-reduce-profit

v1.0.4

Published

A mongoose plugin to help ease mongo increment map-reduce jobs

Downloads

24

Readme

mongoose-map-reduce-profit

A mongoose plugin to help ease mongo/mongoose incremental map-reduce jobs

Creating incremental map-reduce jobs is a pain because testing is difficult. This plugin helps you by creating a way to define a job and then offering a way to test your job outside of mongo where you can set breakpoints and use console.log. This plugin also offers automatic job tracking so you don't have to keep track of the last run date. You may define as many jobs as necessary on a given collection.

Defining Map Reduce Jobs

You can define your job in your mongoose schema or in separate files. This plugin adds a defineIncrementalMapReduceJob() function to mongoose schemas. Start by calling defineIncrementalMapReduceJob with a unique job name and then defining your job details with the returned Job object. You should define all of your jobs at the same time you define all of your mongoose models.


var job1 = TaskSchema.defineIncrementalMapReduceJob( "job1" );
job1.out = "job1-results";
job1.verbose = true;

job1.buildQuery = function( runSpec ){
    if( runSpec.incremental ){
        // This is an incremental job, fetch only the new documents
        return { createdDate: { $gt: runSpec.runDate } };
    }else{
        // This is a full job, fetch all the things
        return {}; 
    }
};

job1.map = function(){
    var MS_IN_DAY = 24*60*60*1000;
    
    var startDate = new Date( this.openedDate.getFullYear(), this.openedDate.getMonth(), this.openedDate.getDate(), 0, 0, 0, 0 );
    var endDate = new Date( this.closedDate.getFullYear(), this.closedDate.getMonth(), this.closedDate.getDate(), 0, 0, 0, 0 );
    var currentDate = startDate;
    
    while( currentDate <= endDate ){
        var dayString = currentDate.getFullYear() + "-" + currentDate.getMonth() + "-" + currentDate.getDate();
        if( currentDate.getTime() === endDate.getTime() ){
            emit( dayString, { open: 0, closed: 1 } );
        }else{
            emit( dayString, { open: 1, closed: 0 } );
        }
        currentDate = new Date( currentDate.getTime() + MS_IN_DAY );
    }
};

job1.reduce = function( key, values ){
    var totals = { open: 0, closed: 0 };
    for( var n = 0; n < values.length; n++ ){
        var record = values[n];
        totals.open += record.open;
        totals.closed += record.closed;
    }
    return totals;
};

The job object has the following customizable properties:

  • buildQuery( runSpec ) - Required. The build query should return a mongoose query based on the passed in runSpec. The runSpec has an incremental property which is a boolean for whether or not a full run is needed. Your query should use the runSpec.runDate property to build a query to return the subset of records for your incremental job when runSpec.incremental is true.
  • map - Required. The map function which will run inside mongo. The map function is responsible for calling emit( key, value ) zero or more times for each record. The map function is called once per record and the current record is the this object. more info
  • reduce( key, values ) - Required. The reduce function which will run inside mongo. The reduce function is responsible for returning some aggregate value for the passed in values array. more info
  • finalize( key, value ) - Optional. The finalize function which will run inside mongo. The finalize function should return a modified object from the passed in reducedValue. more info
  • out - Optional. This can be the name of your output collection as a string or an object which specifies a mongo map-reduce action. more info
  • limit - Optional. The maximum number of records to map-reduce.
  • scope - Optional. An object whose properties will be available in the global scope of the map, reduce, & finalize functions when run inside mongo.
  • scope - Optional. An object whose properties will be available in the global scope of the map, reduce, & finalize functions when run inside mongo. more info
  • verbose - Optional. When true, mongo will output additional info to its log.

Running Map Reduce Jobs

This plugin adds a performIncrementalMapReduceJob function to your models. Run a job by calling performIncrementalMapReduceJob with the proper job name. Be sure you have already defined your jobs by the time your try to run one.

When you call performIncrementalMapReduceJob, the plugin will query to see if the job has ever run before. If the job has been run, the buildQuery function will be called with a runSpec that has runSpec.incremental set to true and runSpec.runDate equal to the last date the job was run.

Task.performIncrementalMapReduceJob( "job1", function( error, results ){
    // console.log( "GOT RESULTS", results, error ); // This won't work because it is run inside of mongo
});

Testing Map Reduce Jobs

This plugin adds a debugIncrementalMapReduceJob function to your models. Test a job by calling debugIncrementalMapReduceJob with the proper job name. Be sure you have already defined your jobs by the time your try to test one.

Task.debugIncrementalMapReduceJob( "job1", function( error, results ){
    console.log( "GOT RESULTS", results, error ); // THIS WORKS!
});

Since the job tests are not run inside of mongo you can set breakpoints and use console.log.

##Example

You can find an example of testing a job using mocha in the /test/main.test.js file. To run the test download this project and run grunt test. Note: You'll need to have mongodb running when you run the tests.