12
\$\begingroup\$

I'm using mongoose to seed a mongodb database based on my mongoose models. I'm particular interested in improving the seed code.

I have two models, an article and a category. The relationship between the models are as follows:

A category has many articles An article has a parent category

The model schemas I'm using are listed below:

The category schema

var mongoose = require('mongoose');

var categorySchema = mongoose.Schema({
    title: String,
    articles : [{ type: mongoose.Schema.Types.ObjectId, ref: 'Article' }]
});

mongoose.model('Category', categorySchema);

The article schema

var mongoose = require('mongoose');

var articleSchema = mongoose.Schema({
    category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' },
    title: String
});

mongoose.model('Article', articleSchema);

I'm using the following code to seed:

Seeding the category

var CategoryModel = require('mongoose').model('Category');

exports.seedCategories = function seedCategories() {
    CategoryModel.find({}).exec(function (err, collection) {
        if (collection.length === 0) {
            CategoryModel.create({ title: 'Category One' });
            CategoryModel.create({ title: 'Category Two' });
        }
    });
}

Seeding the article

var CategoryModel = require('mongoose').model('Category');
var ArticleModel = require('mongoose').model('Article');

exports.seedArticles = function seedArticles() {

    ArticleModel.find({}).exec(function (err, collection) {
        if (collection.length === 0) {
            seedArticle('Category One', 'Article One');
            seedArticle('Category One', 'Article Two');
            seedArticle('Category Two', 'Article Three');
            seedArticle('Category Two', 'Article Four');
        }
    });

    function seedArticle(categoryTitle, articleTitle) {
        var parentCategory;
        CategoryModel.findOne({ title: categoryTitle }).exec()
            .then(function (category) {
                parentCategory = category;
                return ArticleModel.create({ title: articleTitle, _category: parentCategory._id });
            }).then(function (article) {
                parentCategory.articles.push(article._id);
                parentCategory.save(function (saveError) {
                    if (!saveError) {
                        console.log("Seeded article");
                    } else {
                        console.log(saveError);
                    }
                });
            });
    }
}

I'm particularly interested in methods for preventing the Christmas tree of doom, and removing the obstruent error handling. Any recommendations are welcome, and thanks in advance for the help. I hope this code helps others.

Mongoose have just implemented promises returned from saves, so that should help. It will be available in mongoose 3.10.

\$\endgroup\$
1
  • \$\begingroup\$ Why are you assigning the value parentCategory._id of the article to the field _category? The schema defines it as category. Am I misunderstanding something? \$\endgroup\$
    – Pete
    Sep 22, 2019 at 13:29

1 Answer 1

5
\$\begingroup\$

It seems that you are storing the data with double links (article -> category AND category -> articles).

I assume that you need to report on articles for a category. I would simple create an index on Category like this:

var articleSchema = mongoose.Schema({
    category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category', index: true },
    title: String
});

This way you can simplify your code a ton by keeping it KISS:

function seedArticle(categoryTitle, articleTitle) {
  CategoryModel.findOne({ title: categoryTitle }).exec()
    .then(function (category) {
      return ArticleModel.create({ title: articleTitle, category: category._id });
    });
}

Other than that, I like your code.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for your input. My reason for maintaining both links is the ability to use mongoose populate from the parent. But your suggestion is appealing as the code is tidier. Any other recommendations or pointers on how to achieve this are most welcome. Thanks again. \$\endgroup\$ Feb 20, 2014 at 0:02
  • \$\begingroup\$ what is the name and where is the file stored,? I am asking this regarding the second code snippet. \$\endgroup\$ Apr 16, 2015 at 13:28
  • \$\begingroup\$ I too would like to know where/in which file is this code stored so node executes it and takes advantage of the mongoose schemas that are already in the models folder. \$\endgroup\$
    – LaserBeak
    Sep 24, 2015 at 15:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.