I have a model something like this:
Users:
[
{
Name: "John",
Family: "Walker",
Country: "CA",
Questions: [
{Question: "How I can do something...", Answer: "just do nothing."},
{Question: "How I can do something...", Answer: "just do nothing."},
{Question: "How I can do something...", Answer: "just do nothing."}
]
},
more user models
]
And I wanna sent them to Stimulsoft report as businessObject and show users list with their questions in datasource.
I have been added Users model to my User business object, but I don't know how I can show questions of each user.
I have been tried to add a datasource component in user's data source component, but looks like this cannot be done!
Related
Summary:
I am building my first large scale full stack application(MERN stack) that is trying to mimic a large scale clothing store. Each article of clothing has many 'tags' that represent its features, top/bottom/accessory/shoes/ect, and subcategories, for example on top there is shirt/outerwear/sweatshirt/etc, and sub-sub-categories within it, for example on shirt there is blouse/t-shirt/etc. Each article has tags for primary colors, hemline, pockets, technical features, the list goes on.
Main question:
how should I best organize the data in mongodb with mongoose schemas in order for it to be quickly searchable when I plan on having 50,000 or more articles? And genuinely curious, how do large clothing retailers typically design databases to be easily searchable by customers when items have so many identifying features?
Things I have tried or thought of:
On the mongoDB website there is a recommendation to use a tree structure with child references. here is the link: https://docs.mongodb.com/manual/tutorial/model-tree-structures-with-child-references/ I like this idea but I read here: https://developer.mongodb.com/article/mongodb-schema-design-best-practices/ that when storing over a few thousand pieces of data, using object ID references is no longer sufficient, and could create issues because of datalimits.
Further, each clothing item would fall into many different parts of the tree. For example it could be a blouse so it would be in the blouse "leaf" of the tree, and then if its blue, it would be in the blue "leaf" of the tree, and if it is sustainably sourced, it would fall into that "leaf" of the tree as well. Considering this, a tree like data structure seems not the right way to go. It would be storing the same ObjectID in many different leaves.
My other idea was to store the article information (description, price, and picture) seperate from the tagging/hierarchical information. Then each tagging object would have a ObjectID reference to the item. This way I could take advantage of the propogate method of mongoose if I wanted to collect that information.
I also created part of the large tree structure as a proof of concept for a design idea I had, and this is only for the front end right now, but this also creates bad searches cause they would look like taxonomy[0].options[0].options[0].options[0].title to get to 'blouse'. Which from my classes doesnt seem like a good way to make the code readable. This is only a snippet of a long long branching object. I was going to try to make this a mongoose schema. But its a lot of work and I wanna make sure that I do it well.
const taxonomy = [
{
title: 'Category',
selected: false,
options: [
{
title: 'top',
selected: false,
options: [
{
title: 'Shirt',
selected: false,
options: [
{
title: 'Blouse',
selected: false,
},
{
title: 'polo',
selected: false,
},
{
title: 'button down',
selected: false,
},
],
},
{
title: 'T-Shirt',
selected: false,
},
{
title: 'Sweater',
selected: false,
},
{
title: 'Sweatshirt and hoodie',
selected: false,
},
],
},
Moving forward:
I am not looking for a perfect answer, but I am sure that someone has tackled this issue before (all big businesses that sell lots of categorized products have) If someone could just point me in the right direction, for example, give me some terms to google, some articles to read, or some videos to watch, that would be great.
thank you for any direction you can provide.
MongoDB is a document based database. Each record in a collection is a document, and every document should be self-contained (it should contain all information that you need inside it).
The best practice would be to create one collection for each logical whole that you can think of. This is the best practice when you have documents with a lot of data, because it is scalable.
For example, you should create Collections for: Products, Subproducts, Categories, Items, Providers, Discounts...
Now, when you creating Schemas, instead of creating nested structure, you can just store a reference of one collection document as a property of another collection document.
NOTE: The maximum document size is 16 megabytes.
BAD PRACTICE
Let us first see what would be the bad practice. Consider this structure:
Product = {
"name": "Product_name",
"sub_products": [{
"sub_product_name": "Subpoduct_name_1",
"sub_product_description": "Description",
"items": [{
"item_name": "item_name_1",
"item_desciption": "Description",
"discounts": [{
"discount_name": "Discount_1",
"percentage": 25
}]
},
{
"item_name": "item_name_2",
"item_desciption": "Description",
"discounts": [{
"discount_name": "Discount_1",
"percentage": 25
},
{
"discount_name": "Discount_2",
"percentage": 50
}]
},
]
},
...
]
}
Here product document has sub_products property which is an array of sub_products. Each sub_product has items, and each item has discounts. As you can see, because of this nested structure, the maximum document size would be quickly exceeded.
GOOD PRACTICE
Consider this structure:
Product = {
"name": "Product_name",
"sub_products": [
'sub_product_1_id',
'sub_product_2_id',
'sub_product_3_id',
'sub_product_4_id',
'sub_product_5_id',
...
]
}
Subproduct = {
"id": "sub_product_1_id",
"sub_product_name": "Subroduct_name",
"sub_product_description": "Description",
"items": [
'item_1_id',
'item_2_id',
'item_3_id',
'item_4_id',
'item_5_id',
...
]
}
Item = {
"id": "item_1_id",
"item_name": "item_name_1",
"item_desciption": "Description",
"items": [
'discount_1_id',
'discount_2_id',
'discount_3_id',
'discount_4_id',
'discount_5_id',
...
]
}
Discount = {
"id": "discount_1_id",
"discount_name": "Discount_1",
"percentage": 25
}
Now, you have collection for each logical whole and you are just storing a reference of one collection document as a property of another collection document.
Now you can use one of the best features of the Mongoose that is called population. If you store a reference of one collection document as a property of another collection document, when performing querying of the database, Mongoose will replace references with the actual documents.
I am new to MongoDB and mongoose. I am trying to create a Node & MongoDB auction app. So since it is actually an online auction, users should be able to bid for items. I successfully completed the user registration, sign in page and authentication process, however, I am a bit stuck in the bidding page.
I created a Schema using mongoose and each item for auction is saved in the database. I want to add name and price of each user who bid for the item in the same object in MongoDB, like this:
{
name: "valuable vase from 1700s",
owner: "John Doe",
itemId: 100029,
bids: {
100032: 30000,
100084: 34000
}
}
So each user will have ids like 100032: 30000, and when they bid, their "account id: price" will be added under bids in the database object of the item.
I made some research and found some ways to solve the problem but I want to know if what I want to do is possible and if it is the right solution to do.
Thanks for giving me your time!
There are indeed couple of ways to achieve what you want.
In my opinion, a collection called ItemBids, where each document includes this data structure, will benefit you the most.
{
itemId: ObjectId # reference to the item document
accountId: ObjectId # reference to the account
bid: Number # the bid value
}
This pattern is suitable for your case because you can easily query the bids by whatever you want -
You can get all the account bids, you can get all the item bids, and you can sort them with native Mongo by the bid price.
Every time there's a bid, you insert a new document to this collection.
Another option is embedding an array of Bids objects in the item Object.
Each Bid object should include:
bids: [{
account: ObjectId("") # This is the account
price: Number
}]
The cons here are that querying it and accessing it will require more complex queries.
You can read more about the considerations
here:
https://docs.mongodb.com/manual/core/data-model-design
https://coderwall.com/p/px3c7g/mongodb-schema-design-embedded-vs-references
The way you decided to implement your functionality is a little bit complicated.
It is not impossible to do that but, the better way is to use array of objects instead of a single object like this:
{
name: '',
..
..
bids: [{
user: 100032,
price: 30000
}, {
user: 100084,
price: 34000
}]
}
I'm building an app where a user object has multiple game objects. What would be the proper strategy for fetching all of a user's games from a mongoDB database?
As far as I can tell I have 2 options:
Give users a game property that is an array of ids of games that the user has and then fetch each game individually
e.g.
example user
{
_id: '1342',
name: 'Dave',
games: [
'12345678',
'fgnhe45rnd',
],
}
example game
{
_id: '12345678',
name: 'Fluxx',
}
The opposite. Give each game a users property that is an array of ids of users that own that game. Then fetch all games that have a specific user's id.
e.g.
example user
{
_id: '1342',
name: 'Dave',
}
example game
{
_id: '12345678',
name: 'Fluxx',
users: [
'1342',
'5783',
],
}
Any advice is appreciated.
Thank you.
Use Case
A user object has multiple game objects
To fetching all of a user's games
I will suggest you use the first option.
Example user
{
_id: '1342',
name: 'Dave',
games: [
'12345678',
'fgnhe45rnd',
],
}
Example game
{
_id: '12345678',
name: 'Fluxx',
}
Reason
As you mentioned in the use case, you are fetching all of a user's games.
First Option
So if you are fetching all of Dave's game, you only need to get Dave's list of games then refer each game to its data. This is 1+n fetch where n is number of game Dave has.
Second Option
If you use the second option, you will need to go through every single game to check if users list in the game contains Dave. And then you have to record the data only if Dave is in the list. This is N fetch where N is total number of games in the database.
In general, N is larger than n+1.
If you need user's games,you should use 1.For example i need kevin's games: you can get kevin's games with 2.?
I'm rather new to working with MongoDB.
In my application, the user can create to-do-lists. I save the data of these to-do-lists to my database using node.js with express framework and mongoose (with a ReactJS front-end), however, the user is supposed to be able to create several to-do-lists and I'm not sure about how to best sort the data of these lists so I can always access the correct data in my corresponding to-do-list.
Let's say I have this schema:
var TodoSchema = new mongoose.Schema({
task: String,
prio: String,
updated_at: { type: Date, default: Date.now },
});
module.exports = mongoose.model("Todo", TodoSchema);
for my database called tododb.
I was first planning on creating a new collection for each new list, but in this question ( how to create a new collection automatically in mongodb ) it says that it would be much better to create one collection for all lists, however, I'm not sure about how you would filter out the correct data in this case.
I imagine that I'm not the first person to encounter this problem, so how is it done usually? What other options do I have besides collections? And how would I access exactly the data that I need?
Edit: I was also thinking about just adding an element called "name" or something similar, where the user could enter a name for the list, and when fetching the data I would iterate over all data and filter out the once whose name matches, however, that seems terribly inefficient.
I'd model a todo list like the following:
{
"_id": "id of the todo list",
"name": "name of the todo list (e.g. daily tasks)",
"tasks" : [
{"name": "drink coffee", priority: 1, updated: "sometime" },
{"name": "write code", priority: 2, updated: "sometime" },
{"name": "drink tea", priority: 3, updated: "sometime" }
]
}
and then put them all in the same collection, if you need to split by user, just add a userId field to the todo list document.
There are people in a city. A city is represented by a mongodb collection called "cities".
The people in the city are either alone or walking togheter with another person in the same city.
The schema is:
{
name: String,
people: [
{
name: String,
status?: String,
walkingWith?: String
}
]
}
Fields "status" and "walkingWith" are the ones I would like to use, if my strategy is correct.
Here are some entries:
var newyorkPeople = [];
newyorkPeople[0] = {"name": "Jack", "status": "alone", "walkingWith": "none"};
newyorkPeople[1] = {"name": "James", "status": "meeting", "walkingWith": "Maria"};
newyorkPeople[2] = {"name": "Robert", "status": "meeting", "walkingWith": "Nina"};
newyorkPeople[3] = {"name": "Steven", "status": "alone", "walkingWith": "none"};
newyorkPeople[4] = {"name": "Maria", "status": "meeting", "walkingWith": "James"};
newyorkPeople[5] = {"name": "Nina", "status": "meeting", "walkingWith": "Robert"};
I then enter a new city with people in it:
db.cities.insert({"name": "New York", "people": newyorkPeople});
Now, the goal is to make it easy for a client(frontend) to describe what people there are in this city. And group them.
First show all the lone people. And then the "couples" that are walking togheter.
Im not sure if the grouping is better to be done in the backend or in the frontend (angular).
In backend (api) Im using express.js. The api could just return all the city document to the frontend. And then the frontend would be responsible to sort/group the people.
In that case, the strategy Im thinking about would be:
Loop through the people and only print the lone people. Those that are walking with somebody, should go in another array.
So the first step, to show all the lone people, is accomplished.
Now, I still need to show couples. First I need to show the couple "James and Maria" and then the couple "Robert and Nina".
Should I create an array for each couple? In the example above, it should create 2 arrays.
However, Im not sure this is the best strategy. Im fine in modifying the db-schema or even to let the backend deliver the grouped people if somebody could come with some good suggestion.
You can use the following(simplified of yours) schema
{
name:Stirng, //name of the person
city:String, //name of the city
status:String, //status
walkingWith:String //name of the person walking with
}
The benefit of using this schema is, it can make your queries easier.
Let's query your need.
1- all people in a city
db.city.aggregate([
{$group:{_id:"$city", people:{$push:"$name"}}}
])
2- all people in a city alone
db.city.aggregate([
{$match:{status:"alone"}},
{$group:{_id:"$city", people:{$push:"$name"}}}
])
3- all people in a city meeting with someone
db.getCollection('demos').aggregate([
{$match:{status:"meeting"}},
{$group:{_id:"$city", people:{$push:{name:"$name", walkingWith:"$walkingWith"}}}}
])