Home > Software design >  mongodb & mongoose: How to auto create new collection when saving a document in it
mongodb & mongoose: How to auto create new collection when saving a document in it

Time:12-01

Program description: I have a program that accepts a post request (request) of a "hometask" with its name, description, importance and group parameters provided. I need the provided group parameter to be identified as a collection name in the database (each collection is going to correspond to specific group and so each group will have a collection of hometasks-documents). Each new document should be created with Mongoose schema object.

Problem: I know that in Python's pymongo when addressing an unexisting collection it's being created automatically, however, in mongoose this turns out not to be the case. I have trouble providing the collection name to the new document-object. When providing {collection: request.group} in a new object in api/hometask.js, the error message started appearing when new requests were made: MongooseError: document must have an _id before saving. I still cannot understand what can be the cause of this problem. I will appreciate any help!

  • Main folder architecture:

enter image description here

  • server.js
const express = require('express')
require('dotenv').config()
const mongoose = require('mongoose')
const morgan = require('morgan')
const path = require('path')

let app = express();

const port = process.env.PORT || 3000;
mongoose.connect(process.env.uri, { useNewUrlParser: true })
.then(db => console.log('[ok] connected to db))
.catch(err => console.error(err))

app.use(express.json())
app.use(express.urlencoded({extended: false}))
app.use(morgan('dev'))
app.use('/api/hometasks', require('./api/hometask'))
app.use('/', express.static(path.join(__dirname, '../dist')))
app.listen(port)
  • api/hometask.js
const express = require('express');
const router = express.Router();

const Record = require('../models/hometask')

router.post('/', async (req, res) => {
    let request = req.body
    const record = new Record(request, {collection:request.group});
    try {
        await record.save();
        res.json({
            status: 'success'
        });  
    } catch (err) {
        console.log(err)
    }
})

module.exports = router
  • models/hometask.js
const mongoose = require('mongoose');
const { Schema } = mongoose;

let Record = new Schema({
  name: {
    type: String,
    required: true
  },
  description: {
    type: String,
    required: true
  },
  importance: {
    type: Boolean,
    required: true
  },
  group: {
    type: String,
    required: true
  }
});

module.exports = mongoose.model('hometask', Record);

CodePudding user response:

In mongoose the collection name is set per model, not per document.

Note that the Model constructor does not take an options object.

You should be setting the collection name in the call to mongoose.model when you create the model, not when you create a document from that model.

  • Related