skip to Main Content

I made a architectural decision to use multiple schemas since it is allowed rather than use different database and having to deal with clusters. I have noticed that when using the model rather than the collection it use the last schema. I’m not sure why that is. Temporarily I moved the schema in question to the end, I need to get to the source of the issue or why this is happening, this is why I proposed the question. I don’t want it to cause problems later. For some logic since the code was already developed and working before adding the new schemas. I don’t want to have to refactor the code since it is working. I have include some code and an example below. I would appreciate some direction.

Backend Schema
search.cjs file

 const productSchema = new mongoose.Schema({
    name:{
    type: String,
    required: true
  },
   _id:{
    type: String,
    required: true
 }

 });
 const wishitemSchema = new mongoose.Schema({
    name:{
    type:String,
    required:true
    }

 });
 const cartitemSchema = new mongoose.Schema({
    _id:{
        type: String
        required: true.

     },
    mame:{
        type:String,
        required:true
    }

  
    }); 

 

module.exports = mongoose.model('Products',  productSchema,  'products');
module.exports = mongoose.model('Wishitems', wishitemSchema, 'wishitems');
module.exports = mongoose.model('Cartitems', cartitemSchema, 'cartitems');

example of query
api
 const Products      = require('../../../Search.cjs');
 const Wishitems     = require('../../../Search.cjs');
 const Cartitems     = require('../../../Search.cjs');

router.post('/getProducts',  async(req, res) =>{
let search = await Products.find({name: {$regex: new RegExp('^'+payload+'.*',
'i')}}).exec();

 .......
 })
 //it will give me data from the last schema.

  // If I try to use this logic above with a collection it won't work use
    .router.get(/getProducts, async(req, res =>{
     db.collection('products').find({})

    ,,,,
   })
 /*This does not work with the logic I'm using above, I have to stick with what works
 so what I did was. Note with the deletes I can use the say for example WishItems vs the 
 collection */

/* When I do this it works as expected*/

 module.exports = mongoose.model('Wishitems', wishitemSchema, 'wishitems');
 module.exports = mongoose.model('Cartitems', cartitemSchema, 'cartitems');
 module.exports = mongoose.model('Products',  productSchema,  'products');

/*Perhaps someone see something with the Products I'm not catching. I appreciate any 
 advice*/

2

Answers


  1. Just create 3 separate modules. You are overwriting the module.exports inside Search.cjs so you are only exporting the last one Cartitems. That means Products, Wishitems and Cartitems are all models derived form the cartitemSchema.

    Using your current schemas make these changes:

    Product.cjs

    const mongoose = require("mongoose");
    const productSchema = new mongoose.Schema({
       _id:{
          type: String,
          required: true
       },
       name:{
          type: String,
          required: true
       }
    });
    module.exports = mongoose.model('Product',  productSchema,  'products');
    

    WishItem.cjs

    const mongoose = require("mongoose");
    const wishitemSchema = new mongoose.Schema({
       name:{
          type:String,
          required:true
       }
    });
    module.exports = mongoose.model('WishItem', wishitemSchema, 'wishitems');
    

    CartItem.cjs

    const mongoose = require("mongoose");
    const cartitemSchema = new mongoose.Schema({
        _id:{
           type: String,
           required: true
        },
        name:{
           type: String,
           required: true
        }
    }); 
    module.exports = mongoose.model('CartItem', cartitemSchema, 'cartitems');
    

    app.js

    //...
    //...
    const Product = require('../../../Product.cjs');
    const WishItem = require('../../../WishItem.cjs');
    const CartItem = require('../../../CartItem.cjs');
    //...
    //...
    

    Here are some tips moving forward:

    1. You don’t need the third parameter in the mongoose.model function because with just mongoose.model('Product', productSchema); mongoose will take the first argument 'Product' and look for the lowercase pluralised collection name automatically. So 'Product' --> 'products' and 'WishItem' --> 'wishitems' etc.
    2. If you can, leave the _id property alone, don’t set it to String. Mongoose automatically adds one and sets it to an ObjectId which has so many benefits built in.
    Login or Signup to reply.
  2. Each module.exports = line is overwriting the previous one.

    Consider if you had an ordinary variable assigned like that:

     x = mongoose.model('Wishitems', wishitemSchema, 'wishitems');
     x = mongoose.model('Cartitems', cartitemSchema, 'cartitems');
     x = mongoose.model('Products',  productSchema,  'products');
    

    You would expect x to have the last value assigned.

    To return multiple things from a module, use an object, like:

     module.exports = {
        Wishitems: mongoose.model('Wishitems', wishitemSchema, 'wishitems');
        Cartitems: mongoose.model('Cartitems', cartitemSchema, 'cartitems');
        Products: mongoose.model('Products',  productSchema,  'products');
     }
    

    Then when requiring that module, name the items:

    { Wishitems, Cartitems, Products } = require('../../../Search.cjs')
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search