DEV Community

Krishna Kurtakoti
Krishna Kurtakoti

Posted on

Database and model design - mongoose

A new user Alan Tang, on Stackoverflow posted a question regarding the top-level design of schemas for database.
The link to the question is here:
https://stackoverflow.com/questions/70345194/node-js-model-with-inner-nested-array/70345760#70345760
More detail information is below:

I have a question about my collection design.
Current design

Code (Part-I):

const customerSchema = mongoose.Schema({ customer_name: { type: String }, purchase_history: [{ amount: { type: Number, default: 0 }, currency: { type: String, require: true }, description: { type: String } }], ...... });

Every time, if a customer purchases a new item, it will push the history into the "purchase_history".
The purpose of "purchase_history" is to let them check their own history.
Is this a good idea? or If you have a good idea, please few free to share.
Thank you

I answered to the above question like this:
I have created 2 different schemas, one for the customer and another for the purchase. Please follow the standard procedure to keep all the service files, model files, controller files in separate folders.
The below is the customer model.

customer.model.js
Code (Part-II):

const mongoose = require('mongoose'); let Schema = mongoose.Schema; const CustomerSchema = mongoose.Schema({ customer_name: { type: String, }, }); const customer = mongoose.model('customer', CustomerSchema); module.exports = customer;

We have the purchase model as:

purchase.model.js
Code (Part-III):

const mongoose = require('mongoose'); let Schema = mongoose.Schema; const customer = require('./customer.model'); var purchaseSchema = new Schema( { customerId: { type: Schema.Types.ObjectId, ref: 'customer' }, amount: { type: Number, default: 0, }, currency: { type: String, required: true, }, description: { type: String, }, }, { timestamps: true } ); module.exports = mongoose.model('purchase', purchaseSchema);

Here, we can see the customer data is stored in customer collection and the purchase data stored in the purchase collection. Each purchase record has a reference field 'customerId' which is the customer's unique identitifer. This field is defined in the purchase model. The customer's purchase history can be fetched by quering for the customerId field.
We can create an api for fetching customer's purchases as:

purchase.service.js
Code (Part-IV):

const purchaseModel = require('./purchase.model'); module.exports.getByCustomerId = async (_customerId) => { try { const purchaseList = await purchaseModel.find({ customerId: _customerId, }); return purchaseList; } catch (err) { throw err.message; } };

DESIGN PRINCIPLE:
The design principle followed here is to avoid duplication as suggested by a Senior developer. It is not good practice to store the same value in different collections, the purchase data being stored in the customer collection as in Alan’s schema.

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay