MongoDB Database schema for ecommerce - node.js

Im currently building a multi User ecommerce app, (like shopify but for another sector). Im using nodejs with mongoDB. What is the best practice to store the orders?
Im currently have this schema:
UserModel{
username,
password,
ownsStore:}
StoreModel{storeID,
owner:,
products:[productarray],
categories:[],
orders:[array with all OrderModel{
orderid:
oderitems}]}
Will the Orders array in the store get to big?
Is it better Practice to put the Orders in a own colloction and assign them to the stores by using find and only saving the ObjectId in the order array of the store?

This schema will create you problems when the data will get bigger. Instead of doing this you should create different object for each order and map them with any unique ID of user.
The problem in this will come when you would like to sort various orders then you have to either use aggregation query which will take more time as compared to normal query or you will have to manually sort orders by using forEach or map functions.
Secondly you will also face problems while updating document if nested arrays comes into play because mongoDB does not provide support for deeply nested arrays so you would have to set again and again the value of array by manually updating array.
If you make different objects then all those things would get easier and faster to do.
I have worked on ecommerce project and have experienced the issues, so I later changed them to different object for each order.
So define a different schema for orders and add a unique ID of user in each order, so that the mapping becomes easy

Related

How to generate test data for mongodb in bulk which has reference to different collections?

I'm working on a Node.JS project with Mongodb as a database. I want to test how the api performs when the db collection has thousands of documents in it.
So I'm trying to fill the collection with test data but the problem here is, I've multiple associations for a single collections, i.e multiple reference fields in collection.
So is there any api available which allows me to generate data that supports reference fields too.
There is an old library for creating dummy data in mongoose: mongoose-dummy. But it doesn't look like it handles referenced documents.
You can also use faker to create eg. addresses, emails, names, numbers etc.
This is one of those things you really need to DIY (though you can use the above libraries to make it easier)
You created your application and models. Only you will be able to make realistic test data. For example, you will need to decide how many documents to create for a comment model on a blog post model based on what either historical data or your expectations if none exists.

Create Mongoose Schema Dynamically for e-commerce website in Node

I would like to ask a question about a possible solution for an e-commerce database design in terms of scalability and flexibility.
We are going to use MongoDB and Node on the backend.
I included an image for you to see what we have so far. We currently have a Products table that can be used to add a product into the system. The interesting part is that we would like to be able to add different types of products to the system with varying attributes.
For example, in the admin management page, we could select a Clothes item where we should fill out a form with fields such as Height, Length, Size ... etc. The question is how could we model this way of structure in the database design?
What we were thinking of was creating tables such as ClothesProduct and many more and respectively connect the Products table to one of these. But we could have 100 different tables for the varying product types. We would like to add a product type dynamically from the admin management. Is this possible in Mongoose? Because creating all possible fields in the Products table is not efficient and it would hit us hard for the long-term.
Database design snippet
Maybe we should just create separate tables for each unique product type and from the front-end, we would select one of them to display the correct form?
Could you please share your thoughts?
Thank you!
We've got a mongoose backend that I've been working on since its inception about 3 years ago. Here some of my lessons:
Mongodb is noSQL: By linking all these objects by ID, it becomes very painful to find all products of "Shop A": You would have to make many queries before getting the list of products for a particular shop (shop -> brand category -> subCategory -> product). Consider nesting certain objects in other objects (e.g. subcategories inside categories, as they are semantically the same). This will save immense loading times.
Dynamically created product fields: We built a (now) big module that allows user to create their own databse keys & values, and assign them to different objects. In essence, it looks something like this:
SpecialFieldModel: new Schema({
...,
key: String,
value: String,
...,
})
this way, you users can "make their own products"
Number of products: Mongodb queries can handle huge dataloads, so I wouldn't worry too much about some tables beings thousands of objects large. However, if you want large reports on all the data, you will need to make sure your IDs are in the right place. Then you can use the Aggregation framework to construct big queries that might have to tie together multiple collectons in the db, and fetch the data in an efficient manner.
Don't reference IDs in both directions, unless you don't know what you're doing: Saving a reference to category ID in subcatgories and vice-versa is incredibly confusing. Which field do you have to update if you want to switch subcategories? One or the other? Or both? Even with strong tests, it can be very confusing for new developers to understand "which direction the queries are running in" (if you are building a proudct that might have to be extended in the future). We've done both which has led to a few problems. However, those modules that saved references to upper objects (rather than lower ones), I found to be consistently more pleasant and simple to work with.
created/updatedAt: Consider adding these fields to every single model & Schema. This will help with debugging, extensibility, and general features that you will be able to build in the future, which might otherwise be impossible. (ProductSchema.set('timestamps', true);)
Take my advice with a grain of salt, as I haven't designed most of our modules. But these are the sorts of things I consider as continue working on our applications.

Firebase Firestore query by subcolletion length

I am trying to query my Firestore collection (in Node.js for my flutter app), and to get the 10 documents which has the most objects in their subcolllection called Purchases (to get the best sellers).
Is it possible in Firestore? Or do I have to keep an int field outside of my subcollection to represent its length?
Thank you!
I thought this was answered recently, but can't find it right now, so...
Firestore queries (and other read operations) work on a single collection, or a group of collections with the same name. They don't consider any data in other (nested or otherwise) collections, nor can they query based on aggregates (such as the number of documents), unless those aggregates are stored in a document in the queried collection.
So the solution is indeed to keep a counter in a document in the collection you are querying against, and updating that counter with every add/delete to the subcollection.

How do you count the amount of documents in a MongoDB collection within Node?

Quite an odd situation, I've tried numerous solutions and I can't seem to crack it.
A lot of the resources I've found only include mongo console commands, I'm not sure how you'd write this in Node.js.
The reason I'm trying to work this out is I'm trying to make each documents 'id' iterate from the last, so the attempt is to find the amount of documents in a collection, add one and then use that number as the 'id' for the new document.
To get the number of documents in a collection, use db.collection.find({}).count().
However, what you are trying to do will not work. When you have a lot of parallel accesses to the database, then it is possible that multiple threads do this at the same time, receive the same count and will thus insert a document with the same id. According to the CAP theorem, a distributed database like MongoDB can not provide this kind of consistency.
What you should do instead is rely on MongoDB ObjectId's as unique identifiers for documents. MongoDB generates these automatically for each document when you don't provide an own value for _id. ObjectId's are globally unique (unique enough for any practical purpose), so you won't get any collisions. They also begin with a timestamp, so when you order by _id you get a roughly chronological order (as previously stated, a strict chronological order is impossible to provide by a distributed system).
As a rule of thumb, whenever you would use AUTO_INCREMENT in SQL, you would likely use ObjectId's in MongodDB.

creating and querying a collection in another collection. mongodb node.js

Is there a way to create and query a collection thats inside another collection...
Can any one direct me to literature that can teach me how to do this?
I've checked the mongodb
docs tutorial and i havent come across this scenario
No code example because i don't know where to start.
Here is what im trying to do.
Im modelling an online shop. So shop object details are in a collection holding many shops.
Now each shop has got products and each product its own unique details. I want to a void using references and rather append but from tutorial from mongodb docs its not quite clear how to do it.
Im fairly new to mongodb
Thanks.
There isn't any such thing as a collection inside another collection with mongo. A collection is a collection of documents.
There are a couple of ways to link documents to other documents, or collections of other data. The correct one to choose is up to you, your data, and your application.
Any document can point to another ObjectId from any field
You can have an array inside a document
Combine the two, and you can have an array of document ids
Mongo is a document store, not a relational database. My suggestion is don't try to use it as a relational database. If what you need is an RDBMS, use one.
Arrays:
http://docs.mongodb.org/manual/reference/operator/query-array/
http://docs.mongodb.org/manual/reference/operator/update-array/
ObjectId:
http://docs.mongodb.org/manual/core/document/

Resources