1.0.3 • Public • Published


A mongoose plugin for handling recently accessed data to be stored on a document

Build Status npm version Coverage Status Code Climate Dependency Status

var mongoose = require('mongoose');
var recentPlugin = require('mongoose-recent');
var CatSchema = new mongoose.Schema({ name: String }).plugin(recentPlugin, {name: 'hairball', schemaType: String});
var Cat = mongoose.model('Cat', CatSchema);
var kitty = new Cat({ name: 'Fang' });
kitty.addRecentHairball('morningHairball', function(err, cat) {
   if (err) // ...
   console.log(cat.recentHairballs[0].hairball); // morningHairball 
// You can also add hairballs with promises
kitty.addRecentHairball('eveningHairball').spread(function(cat) {
    console.log(cat.recentHairballs[0]); // { hairball: 'eveningHairball', date: Tue May 05 2015 10:17:53 }

(see a working example of this in examples/)


mongoose-recent adds a new collection to your document, along with instance and static methods for adding recent items. This collection is kept in a date-sorted order (newest at the top), and by default does not allow duplicates and has a maximum size of 10 entries. If you re-add an entry that already exists in the collection, it will be bubbled back up to the top.

This plugin is intended to be used whenever you find yourself with a collection sorted by date. For example:

  • Recent items that a customer has viewed
  • Recent videos that a user has played
  • Recently clicked buttons

To get started with a minimal plugin, which will add a recentViews collection and an addRecentView(...) function, simply add it to any Schema:

var mongoose = require('mongoose');
var recentPlugin = require('mongoose-recent');
var UserSchema = new mongoose.Schema(...);

Adding to the collection

You can add to the recent items collection either with an instance method on the document, or a static method on the model. You can also use callbacks, which follow the standard mongoose/node callback structure (err, object), or use all the power of bluebird promises.

With Callbacks:

User.addRecentView({_id: someId}, productId, function(err, user) {
    if (err) {
        // ...
    console.log(user.recentViews); // Our new product id is at the top.
var user = new User();
user.addRecentView(productId, function(err, _user) {
    if (err) {
        // ...
    console.log(_user.recentViews); // Our new product id is at the top. 

With Promises:

User.addRecentView({_id: someId}, productId).spread(function(_user) { // Pass in a query, just like you would for find one
    console.log(_user.recentViews); // Our new product id is at the top.
}).catch(function(err) {
    // ...
user = new User();
user.addRecentView(productId).spread(function(_user) { // Note the use of spread instead of then, because save returns (object, numAffected)
    console.log(_user.recentViews); // Our new product id is at the top.
}).catch(function(err) {
    // ...



Type: String
Default: view

In many cases, this is the only option you'll need to set. This should usually be a singular noun and will be used to set the following three things:

  1. The collection, which will be named recent{}s
  2. The instance method, which will be named addRecent{}
  3. The property in the collection, which will be named {}
Schema.plugin(recentPlugin, {name: 'item'});
Model = mongoose.model('Model', Schema);
doc = new Model();
console.log(doc.recentItems); // [], with the schema {item: ObjectId, date: Date}
console.log(doc.addRecentItem); // [Function]

If you'd like more control over how everything is named, see collectionPath, addFunctionName, and dateFieldName.


Type: Number
Default: 10

This controls the number of items to keep in the collection.


Type: Object
Default: DefaultObjectId

By default, this is just a mongo object Id, but can be another id type (for example, String or ShortId), or a complex object.

Schema.plugin(recentPlugin, {schemaType: {name: String, acl: {type: String, 'default': 'user'});
Model = mongoose.model('Model', Schema);
doc = new Model();
console.log(doc.recentViews); // [], with the schema {view: {name: String, acl: {type: String, 'default': 'user'}, date: Date}


Type: Function
Default: ===

By default, mongoose-recent uses === to compare when checking for duplicates. If you have an object as the schema type, this is usually not the desired behavior. Instead, you should define your own custome comparison function. The comparison function is passed the object being added as the first argument, and the object to compare against as the second argument.

var compareFunc = function(o1, o2) {
  return o1.miceCaught === o2.miceCaught;
Schema.plugin(recent, { schemaType: { name: String, miceCaught: Number }, compareFunc: compareFunc } );
// ...


Type: String
Default: recent{}s

You can use this for fine-grained control over how the collection is added to your schema.

Schema.plugin(recentPlugin, {collectionPath: 'recentlyViewedItems'});
Model = mongoose.model('Model', Schema);
doc = new Model();
console.log(doc.recentViews); // undefined
console.log(doc.recentlyViewedItems); // []
console.log(doc.addRecentView); // [Function]


Type: String
Default: addRecent{}

You can use this for fine-grained control over how the addRecent instance method is added to your schema.

Schema.plugin(recentPlugin, {addFunctionName: 'addToRecentlyViewed'});
Model = mongoose.model('Model', Schema);
doc = new Model();
console.log(doc.recentViews); // []
console.log(doc.addRecentView); // undefined
console.log(doc.addToRecentlyViewed); // [Function]


Type: String
Default: date

You can use this for fine-grained control over how the date field is named.

Schema.plugin(recentPlugin, {dateFieldName: 'timeOfAccess');
Model = mongoose.model('Model', Schema);
doc = new Model();
console.log(doc.recentViews); // [], with the schema {view: ObjectId, timeOfAccess: Date}


Type: boolean
Default: false

By default, duplicates are not allowed. If you re-add an item that's already in the collection, it will be given a new date and moved to the top of the collection. If you want to track all recent instances, rather than just the most recent for an item, set this to true. When true, every call to addRecent will add a new entry to the collection.


  • 1.0.3: Relax mongoose peer dependency further
  • 1.0.2: Relax mongoose peer dependency
  • 1.0.1: Fix issue when calling methods
  • 1.0.0: Initial Release



Package Sidebar


npm i mongoose-recent

Weekly Downloads






Last publish


  • jemonjam