Product Catalog with MongoDB - price model - mongodb

I followed Product Catalog with MongoDB, Part 1: Schema Design but i'm not sure how to use it.
My question is how to retrieve products in a specific category with their prices?(like a simple category page in an e-commerce website)
If i put prices in the same collection with products (embed it in the product model) so with a single query i can get price for each product but i don't have as flexibility as second approach(for example variant pricing is impossible).
sample product document:
{
id: '054VA72303012P',
name: 'women's kate ivory',
...
prices: [{
val: 127788.33,
startDate: '2018-12-31 23:59:59',
endDate: '2019-2-31 23:59:59',
}]
}
Second option is to store prices as a separate collection (as it said in the article). But i'm wondering how to retrieve products with their prices. Is it possible to do that with a single query? as MongoDB doesn't have JOIN operation how should i select a product with the corresponding prices. Sample schemas with complete descriptions are available in the article.
Sample schemas:
product_document:{
"_id": '054VA72303012P',
"name": 'women's kate ivory',
...
}
variant_document:{
"_id": "05458452563",
"itemId": "054VA72303012P",
"name": "Width:Medium,Color:Ivory,Shoe Size:6.5",
...
}
price_document:{
"_id": "054VA72303012P_1234",
"price": "69.99",
...
}

Related

How do I get unique values from nested Many-To-Many joins

Basically we have four tables that are joined: Malls, Stores, Brands, and Categories.
Malls can have many Stores.
Each Store is linked to a Brand.
Each Brand has many Categories.
e.g. Mall A has 2 "McDonald's Cafes", each belonging to the Brand "McDonald's". "McDonald's" Brand has "Fast Food" and "Breakfast" as Categories.
We're trying to figure out how to display all the Categories that exist within Mall A.
e.g. Mall A has "Fast Food" and "Breakfast" categories, based on the "McDonald's" stores.
Ideally this would be a query so that the Categories are updated automatically.
We've tried querying for all Stores within a Mall, and then finding the Categories via the Store-Brand join, then reducing duplicates. But some Malls have more than 700 Stores, so this process is quite expensive in terms of querying and processing the data.
I managed to figure it out! Using Sequelize, my query was as follows:
postgres.BrandsCategories.findAndCountAll({
limit,
offset,
include: [
{
model: postgres.Brands,
as: "brands",
include: [
{
model: postgres.Stores,
as: "stores",
where: {
mallId: parent.dataValues.id
}
}
]
}
]
})

Algolia Group Results

I have the following scenario of records
ProyectA APARTMENT 1 specs of the apartment
ProyectA APARTMENT 2 specs of the apartment
ProyectB APARTMENT 1 specs of the apartment
ProyectB APARTMENT 2 specs of the apartment
I will like to only show as result a group of the proyect, example:
Results 2:
ProyectA
ProyectB
*If you have another approach to this scenario that we can structure our data please let us know, keep in mind that every apartment has different specifications like pricing , measurements etc...
What you can do is using the distinct and attributeForDistinct features to group results based on one of their common attributes.
Let's imagine the following records:
[
{
"project": "Alpha",
"apartment": "Skylines"
},
{
"project": "Alpha",
"apartment": "Cozy"
},
{
"project": "Beta",
"apartment": "Skyfall"
},
{
"project": "AAA",
"apartment": "Cortana"
}
]
If you define in your index distinct: true and attributesForDistinct: project, then your results will only ever contain one of project Alpha and one of Project Beta.
Which one will it be will depend on your other relevance settings. The most relevant result for each project (according to you current search) will always be returned. So for example if you're searching for "Sky", you will have the Skylines from Alpha and the Skyfall from Beta.
If you're not searching for any keyword, then they will be ordered by what you defined in your customRanking (it can be by price, by popularity, etc).

Storing country state city in MongoDB

I am currently working on building database to store country-state-city information which is later to be used from drop down menus in our website.
I wanted to get few suggestions on the schema that I have decided as to how efficiently it will work.
I am using MongoDB to store the data.
The schema that I have designed is as follows:
{
_id: "XXXX",
country_name: "XXXX",
some more fields
state_list:[
{
state_name: "XXXX",
some more fields
city_list:[
{
city_name : "XXXX",
some more fields
},
{
city_name : "XXXX",
some more fields
}
]
}
]
}
The data will be increasing. Also there is a long list of cities for each state.
How good this schema will work for the intended purpose?
Should I use linking documents technique (this will require manual coding to map the _id) ?
I would suggest to keep it 1-N on country with respect to state while city to be separate collection with stateid.
You will have each country with limited number of states, while state will have many cities.
Making cities embedded in state and then states embedded in country will make the country collection too huge.
The common notion for making schema design is based on following criteria:
1-Few (in this case embed the collection inside parent object.
1-many (in this case create array of ids inside the parent collection and keep chil collection as seperate.
1- scillions (in this scenario keep the parent id in the child object and keep them as separate collections.
This link explains it much better.
I think as your data will increase , this schema will collapse. The best way is to break the database in 3 schemas and use refrence of their Ids.
Country Schema:
{
_id: "XXXX",
country_name: "XXXX",
some more fields
state_list:[{
"_id": reference id to state object
}]
}
State Schema :
{
_id: "XXXX",
state_name: "XXXX",
some more fields
city_list:[{
"_id" : reference to city object
}]
}
City Schema:
{
_id: "XXXX",
city_name: "XXXX",
some more fields
}

MongoDB many-to-many relationship logic

I'm trying to design a schema for Products, Suppliers and Manufacturers:
A product can have many suppliers but only 1 manufacturer.
A supplier can have many products and many manufacturers.
A manufacturer can have many suppliers and many products.
I've reviewed this page where 10gen indicates "To avoid mutable, growing arrays, store the publisher reference inside the book document". In my example I consider the product-->manufacturer relationship to be equivalent to that of book-->publisher. I would therefore do this:
{
_id: "widgets",
manufacturer_name: "Widgets Inc.",
founded: 1980,
location: "CA"
}
{
_id: 123456789,
product_name: "Steel Widget",
color: "Steel",
manufacturer_id: "widgets"
}
{
_id: 223456789,
product_name: "White Widget",
color: "White",
manufacturer_id: "widgets"
}
What is the best way to handle the SUPPLIER (with relationships to many products and many manufacturers) such that I "avoid mutable, growing arrays"??
Note: This is one way to model it. Data modeling has a lot to do with the use cases and the according questions you want to ask. Your use case might need a different model.
I'd probably model it like this
manufacturer
{
_id:"ACME",
name: "ACME Corporation"
ā€¦
}
products
{
_id:ObjectId(...),
manufacturer: "ACME",
name: "SuperFoo",
description: "Without SuperFoo, you can't bar or baz!",
ā€¦
}
Now comes the problem. Since potentially, if we embed all the products in a supplier document or vice versa, we could break the 16MB size limit easily, I'd use a different approach:
Supplier:
{
_id:ObjectId(...),
"name": "FooMart",
"location: { city:"Cologne",state:"MN",country:"US",geo:[44.770833,-93.783056]}
}
productSuppliers:
{
_id:ObjectId(...),
product:ObjectId(...),
supplier:ObjectId(...)
}
This way, each product can have gazillions of suppliers. Now here come the drawbacks.
For finding a supplier for a certain product, you have to do a two step query. First, you have to find all supplier IDs for a given product:
db.productSuppliers.find({product:<some ObjectId>},{_id:0,supplier:1})
Now, let's say we want to find all suppliers of SuperFoo near Cologne,MN at a max distance of 10 miles:
db.suppliers.find({
_id:{$in:[<ObjectIds of suppliers from the first query>]},
"location.geo": { $near :
{
$geometry: { type: "Point", coordinates: [ 44.770833, -93.783056] },
$maxDistance: 16093
}
}
})
You need to do quite some smart indexing to make these queries efficient. Which indices you need depends on your use case. The problem with indices is that they are only efficient when kept in RAM. So you really should be careful when creating your indices.
Again: The way you model data heavily depends on your use cases. In case you only have a few products per manufacturer or only a few suppliers per product or if each supplier only supplies products by a certain manufacturer, the model may look quite different.
Please have a close look at MongoDB's data modeling documentation. Most problems with MongoDB stem from wrong data modeling for the respective use case.

MongoDb - Embedding or reference?

I come from SQL relation world, and have a question that involves mongodb schema design.
The reality that i need to represent contains:
Users, and monthly reports (with multiple daily reports).
I want to figure out if in mongodb, is better to embedded reports objects into the Users collection, or to have 2 separate collection referenced by id.
Embedded solution:
User:{
name:
surname:
monthlyReports: [{
month: "January 2014"
dailyReport: [{
day: 1
singleReport: [
{ report1}, {report2}, ...
]
}, {
day: 2
singleReport: [
{ report1}, {report2}, ...
]
}
]
},
{
/*
february 2014
Day 1
Day 2 ...
*/
} ...
]
}
Referenced solution:
Users:{
name:
surname:
monthlyReports: [
id_reportMonth1, id_reportMonth2, ...
]
}
MonthlyReport: {
id:
month:
dailyReport: [{
day: 1
singleReport: [
{ report1 }, { report2 } ...
]
},
{
} ....
]
}
For single user, i need to retrive single daily report, monthly report, and total report.
I think that in embedded solution, querying is more simple, but create large object in a long period.
Another possibility:
Create 3 referenced collection:
User, monthlyReport, dailyReport.
What is the better way to do it?
Someone has suggested?
Mongo wrote an excellent 3 parts blog post about it: http://blog.mongodb.org/post/87200945828/6-rules-of-thumb-for-mongodb-schema-design-part-1
Bottom line: it depends on the use.
You need to consider two factors (ref: mongodb blog post) :
Will the entities on the ā€œNā€ side of the One-to-N ever need to stand alone?
What is the cardinality of the relationship: is it one-to-few; one-to-many; or one-to-squillions?
Based on these factors, you can pick one of the three basic One-to-N schema designs:
Embed the N side if the cardinality is one-to-few and there is no
need to access the embedded object outside the context of the parent
object
Use an array of references to the N-side objects if the cardinality
is one-to-many or if the N-side objects should stand alone for any
reasons
Use a reference to the One-side in the N-side objects if the
cardinality is one-to-squillions
Hope this helps.