Baloo
Baloo

Reputation: 33

How to create subdocument on mongodb dynamically

I have a mongodb database with a collection as follow:

var mongoose = require('mongoose');
var journalSchema = mongoose.Schema({
  title : String,
  journalid: {type:String, index: { unique: true, dropDups: true }},
  articleCount : type:Number, default:1,
});
module.exports = mongoose.model('Journal', journalSchema);

Now that my database is growing, I would like to have a "articles count" field per year.

I could make an array as follow years : [{articleCount : Number}] and fill it up by accessing journal.years[X] for a specific year, where X correspond to 0 for 1997, 1 for 1998, etc..

However, my data are scrapped dynamically and I would like to have a function in my express server where articleCountis increased based on the year.

For example:

function updateYear(journalid, year, callback) {
  Journal.findOneAndUpdate(
    {'journalid':journalid},
    {$inc : {'articleCount' : 1}}, // DO SOMETHING WITH year HERE
    function() {
      callback();
    });
}

This does increase the article count but I don't know where to include the "year"...

What would be the fastest way of doing that, knowing that I have to fetch through quite a lot of articles (10 millions +) and I would like to be able to get/update the article count for a given year efficiently.

Hope I'm clear enough, Thanks!

Upvotes: 1

Views: 501

Answers (1)

chrisbajorin
chrisbajorin

Reputation: 6153

Make your array a set of objects with a year and count:

journalYears: [
    {
        year: String, // or Number
        count: Number
    }
]

e.g.

journalYears: [
    { year: "2014", count: 25 },
    { year: "2015", count: 15 }
]

Then for your update:

function updateYear(journalId, year, callback) {
    Journal.findOneAndUpdate(
        {_id: journalId, "journalYears.year": year},
        { $inc: { "journalYears.$.count": 1 } },
        callback
    );
}

The index of the first match from your query is saved in $. It's then used to update that specific element in your array.

Upvotes: 1

Related Questions