Mongoose model data deeper than 1 level - mongodb

I'm trying to design my schema in Mongoose which contains the following collections:
Customers
Expenses
Categories
Instead of embedding the expenses within the customer, I have decided to create its own collection as a customer could potentially have thousands of expenses.
My first question is, is that the best way to model this? i.e. In the expenses collection, would it be best to have a single document for each expense that has a reference to the customer it belongs to?
My second question is about modeling the expenses.
I want to have something like this (oversimplified it here):
{
"_id": Object,
"customer_ref": Object,
"details": {
"amount": 20.00,
"description": "An expense"
},
"date_created": "April 5th..."
}
I have been able to create schema models where the data is one level deep but I'm not sure how you achieve something like the above where I have nested data.
Is mongoose designed to only deal with one level deep data, so I should avoid nesting altogether?
If not how do I achieve something like the above?

Related

Best document model to store students and completed trainings in MongoDB

I have two models named Students, Trainings. I want to store student's completed trainings.
Currently my Student model is like below:
{
"_id": "abcd"
"name": "Student 1"
"completedTrainings": ["asds", "asdasd"]
}
When I list completed trainings, I'm getting all trainings with $in.
Is it right way to my use case, are there better alternatives ?

MongoDB design speculation

I am digging the MongoDB related questions/answers but one thing is still not obvious.
Let's consider the following Product collection:
{
"manufacturer": "Man1",
"model": "Model1"
}
Let's say we have 1.000.000 products, and I would like to create
a dropdown of manufacturers (which would be max 50 options).
In this case every time I have to use the .distinct() function on that huge product collection.
Is this the right way to do it ?
I am a bit concerned about the performance.
Or should I create a separate collection for manufacturers and keep it synced ?
UPDATE
Thanks for all the answers, I still considering them.
And what if I do the following:
Manufacturer:
{
"name": "Man1",
"models": [
{
"name": "Model1",
"products": [Product1, Product2]
}
],
}
and Product
{
"manufcturer": "Man1",
"model": "Model1"
"manufacturer_id": Manufacturer1,
"model_id", Model1
}
First. If you've large number of records, you'd never want to load all the data in just one request to populate the list, dropdown or whatever it is. Rather, implementing something like load more options suits more. Just like pagination.
And you can manage to get like 20,40 records per request and do any optimization on those small chunk of data.
You can create a separate collection for manufacturers. You just have to keep it in sync, after every addition/update/deletion of product from products collection.
I think you can think of designing your Product collections like this:
{
"manufacturer": "Man1",
"model": "Model1"
"Product" :[Product1,Product2]
}
And having an index on "manufacturer" will optimize your query to get list of manufacturers

How to design product category and products models in mongodb?

I am new to mongo db database design,
I am currently designing a restaurant products system, and my design is similar to a simple eCommerce database design where each productcategory has products so in a relational database system this will be a one (productcategory) to many products.
I have done some research I do understand that in document databses.
Denationalization is acceptable and it results in faster database reads.
therefore in a nosql document based database I could design my models this way
//product
{
name:'xxxx',
price:xxxxx,
productcategory:
{
productcategoryName:'xxxxx'
}
}
my question is this, instead of embedding the category inside of each product, why dont we embed the products inside productcategory, then we can have all the products once we query the category, resulting in this model.
//ProductCategory
{
name:'categoryName',
//array or products
products:[
{
name:'xxxx',
price:xxxxx
},
{
name:'xxxx',
price:xxxxx
}
]
}
I have researched on this issue on this page http://www.slideshare.net/VishwasBhagath/product-catalog-using-mongodb and here http://www.stackoverflow.com/questions/20090643/product-category-management-in-mongodb-and-mysql both examples I have found use the first model I described (i.e they embed the productCategory inside product rather than embed array of products inside productCategory), I do not understand why, please explain. thanks
For the DB design, you have to consider the cardinality (one-to-few, one-to-many & one-to-gazillions) and also your data access patterns (your frequent queries, updates) while designing your DB schema to make sure that you get optimum performance for your operations.
From your scenario, it looks like each Product has a category, however it also looks like you need to query to find out Products for each category.
So, in this case, you could do with something like :
Product = { _id = "productId1", name : "SomeProduct", price : "10", category : ObjectId("111") }
ProductCategory = { _id = ObjectId("111"), name : "productCat1", products : ["productId1", productId2", productId3"]}
As i said about data access patterns, if you always read the Category-name and "Category-name" is something which is very infrequently updated then you can go for denormalizing with this two-way referencing by adding the product-category-name in the product:
Product = { _id = "productId1", name : "SomeProduct", price : "10", category : { ObjectId("111"), name:"productCat1" }
So, with embedding the documents, specific queries would be faster if no joins would be required, however other queries in which you need to access embedded details as stand-alone entities would be difficult.
This is a link from MongoDB which explains DB design for one-to-many scenario like you have with very nice examples in which you would realize that there are much more ways of doing it and many other things to think about.
http://blog.mongodb.org/post/88473035333/6-rules-of-thumb-for-mongodb-schema-design-part-3 (also has links for parts 1 & 2)
This link also describes the pros & cons for each scenario enabling you to reach a narrow down on a DB schema design.
It all depends on what queries you have in mind.
Suppose a product can only belong to one category, and one category applies to many products. Then, if you expect to retrieve the category together with the product, it makes sense to store it directly:
// products
{_id:"aabbcc", name:"foo", category:"bar"}
and if you expect to query all the products in a given category then it makes sense to create a separate collection
// categories
{_id:"bar", products=["aabbcc"]}
Remember that you cannot atomically update both the products and categories database (MongoDB is eventually consistent), but you can occasionally run a batch job which will make sure all categories are up-to-date.
I would recommend to think in terms of what kind of information will I often need, as opposed to how to normalize/denormalize this data, and make your collections reflect what you actually want.

MongoDB (NoSQL) - Can a document reference/link to itself?

I am very new to the NoSQL side of DBs but I have been using RDBMs for years, primarily MySQL.
Right now, in MySQL, I have a database that holds about 10,000 food items (about to add another 15,000) that contain items, which links to attributes and nutrients. This seemed to be like a good use for NoSQL as far as my research has taken me, but one part makes me think it might not be.
From what I can tell there are absolutely no joins in NoSQL (very happy for the simplicity), but right now we have several food items that are somewhat the same, and they are going to all reference one, for instance:
Tomatoes, Raw
Tomatoes, Canned
Tomatoes, Cooked
What I am going to do is make all of them reference the main object, "Tomatoes, Raw" or just "Tomatoes", but they all contain their own set of attributes and nutrients, and are rightfully their own "food item".
In RDBM this is simple, simply adding a primary_item_id field to the item table and referencing the main item.
Is this possible in MongoDB, or should I stick with MySQL?
-Kerry
You can use the same thing in MongoDB i.e. Tomatoes can be main item with say _id=1 and these items will have parent id as 1. The collection can be noted as:
{ { 1, "Tomatoes", null }, { 2, "Tomatoes, Raw", 1 }, { 3, "Tomatoes, Canned", 1 }, { 4, "Tomatoes, Cooked", 1 } }
Note that you can keep parentid in main item as null for query purposes (as I did above) or you can just remove that column if you do not need it (and it works as MongoDB is schema free.)

Mongo DB chained query

I am new to MongoDB and as I wonder if a chained query like the following is possible(somewhat like a join):
db.places.insert({
"_id": original_id
"place_name": "Broadway Center"
"url": "bc.example.net"})
db.people.insert({
"name": "Erin"
"places_id": original_id
"url": "bc.example.net/Erin"})
So given a place name string, I want to select the people associated with that place.
But the people collection only reference the place id, not the place name.
You cannot use joins in MongoDB.
The idiomatic solution is retrieve all place_ids for that place_name from your places collection and then use the place_ids to query in your people collection.
Another option is keeping, for example, places in people collection (this makes more sense to me than people inside places collection but, of course, it depends on your domain). But then you have to take into account that in case that only one place changes, you have to change all people documents sharing a specific place. If people and places are in separate collections this doesn't happen so it depends on if we have static data or not and on if we want to optimize searches or updates.