Mongo Collection or Document - node.js

I'm looking at the possibility of switching from Filemaker to a MERN app. I get the basic idea of NoSQL databases but its a very different way of thinking. I have recreated what I need in MySQL, but Mongo DB (or Firestore) interests me.
The app is used to record workouts of clients. Each person has many workouts, each workout has many items within it. I'm not sure the best way to do this in Mongo.
I'm between using a collection for all workouts, and each workout has an array of all the items (exercises) they did. Or have the items as a separate collection with a workout_ID to link them up.
Probably the most important thing I'm looking for here is the ability to see all the instances someone did an exercise. From my understanding, if I do it the first way, every single record will be pulled. But the second would only return the documents in that collection that would match exercise_ID and person_ID.
Which is the best approach for such a project?

The second option is the best way to store the data in your case. You can always separate the items in a different collection and store the item Ids in your main collection i.e workouts here.
If you are concerned about querying(joins) them, mongoose provide 'populate' to fetch data between multiple collections using ids as references.
Or you can also use aggregate queries to achieve the same.
hope this helps :)

I think the best option for me would be having an array of the items inside each workout, because that's basically the purpose of using no-SQL databases, to access faster to the data.
However there's a basic rule.. if you think the array of items of each workout it's gonna grow very fast and it will get so big.. then it's better to have a separate collection for the items. if it's not.. then keep those inside an array.
Hope this can be helpful to you.. greetings! :)

Related

MongoDb slow aggregation with many collections (lookup)

i'm working on a MEAN stack project, i use too many collections in my aggregation so i use a lot of lookup, and that impacts negatively the performance and makes the execution of aggregation very slow. i was wondering if you have any suggestions , i found that we can reduce lookup by creating for each collection i need an array of objects into a globale collection however, i'm looking for an optimale and secured solution.
As an information, i defined indexes on all collections into mongo.
Thanks for sharing your ideas!
This is a very involved question. Even if you gave all your schemas and queries, it would take too long to answer, and be very specific to your case (ie. not useful to anyone else coming along later).
Instead for a general answer, I'd advise you to read into denormalization and consider some database redesign if this query is core to your project.
Here is a good article to get you started.
Denormalization allows you to avoid some application-level joins, at the expense of having more complex and expensive updates. Denormalizing one or more fields makes sense if those fields are read much more often than they are updated.
A simple example to outline it:
Say you have a Blog with a comment collection, and a user collection
You want to display the comment with the name of the user. So you have to load the player for every comment.
Instead you could save the username on the comment collection as well as the user collection.
Then you will have a fast query to show comments, as you don't need to load the users too. But if the user changes their name, then you will have to update all of the comments with the new name. This is the main tradeoff.
If a DB redesign is too difficult, I suggest splitting into multiple aggregates and combining them in memory (ie. in your node server side code)

MongoDB - When to add SubDocuments and when to Ref

Im using MongoDB for storing information for a nodeJS application and a doubt came to my mind, after finding that it is possible to use ObjectID to ref another document. As it is known, MongoDB is a no-SQL db, so there is no need for consistency whatsoever and information can be repeated.
So, lets say, I have a collection for users and one of their field values is 'friends', which is an array of this user friends (another users). What is the best practice, saving all the user info there (thus repeating the same thing over and over again throughout the DB) or saving only the ObjectID of the friendUser (makes way more sense to me, but it sounds kinda SQL mindset). I'm not really getting when should I use each of the options, so a professional opinion would be very appreciated.
To model relationships between connected data, you can reference a document or embed it in another document as a subdocument.
Referencing a document does not create a “real” relationship between these two documents as does with a relational database.
Referencing documents is also known as normalization. It is good for data consistency but creates more queries in your system.
Embedding documents is also known as denormalization.
The benefit of Embedding approach is getting all the data you need about a document and it’s sub-document(s) with a single query. Therefore, this approach is very fast. The drawback is that data may not stay as consistent in the database.
Important
If one document is to be used by many documents then better create a referenced doc.
i. Will Save Space.
ii. if any change required, we will have to update only the referenced doc
instead of updating many docs.
Create sub doc(embedded)
i. If another document is not dependent on the subdocument.
Source: https://vegibit.com/mongoose-relationships-tutorial/
Recommended reading:
MongoDB Applied Design Patterns by Rick Copeland
To Embed or Reference

Couchbase retrieving relational docs in nodeJS

I am still debating which way to go and possibly store certain information in its own doc. so for example the customer can have addresses with each address would be its own doc and then in the customer doc there would be an array of ref keys stored under addresses. The benefit would be i could update these docs simply based on the key value vs having to get the customer doc first, finding the array index of the address and then either modify the whole doc or go and use subdoc to replace the content of the array with the index.
Where i am stuck is how to retrieve those referenced subdoc's. is N1QL the only way to go or does the KV API offer a way to do this short of retrieving the whole customer doc, then looping thru address array and retrieving all referenced docs that way. I know Ottoman offers something like that but i am having an issue with the latest version of SDK 2.6 and Ottoman as its not very well maintained. So hopefully someone can share some insight what and why its the best way.
If you want to rely on key/value, then you'll need to do the multiple lookup as you've described. I'm not very familiar with Ottoman: it might do this for you, but behind the scenes it will still be multiple key/value operations and/or N1QL.
With N1QL, you can perform JOINs, but again, behind the scenes it's going to eventually be pulling documents out by key/value. It just does those extra steps for you. Direct key/value is always going to be the fastest route.
If you are still in the process of deciding whether to split the data amongst multiple documents or "denormalize" the data into a single doc, one thing you should think about is how often you're going to access customer+addresses together and how often you're going to customer/access separately. If you're reading/writing customer+address often, consider putting it in one document. Otherwise, consider putting it in multiple documents.
The third option is to store it both places, or rather "cache" the address data in the customer document. This is tricky, because it could get out of sync if you're not careful. So make sure it's worth it before you go down that road.

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/

Link two document with native driver

I have two different collections in my database, and at this point I need to link a document from first collection to a document form second collection with native NodeJs driver.
How can I do that? Should I hold the _id from first collection in second collection?
Yes, I would suggest storing the _id of the related document, manually, as you described. I've done that a lot, and it works well.
A more complex (and seemingly unnecessary in the case you describe), would be to use a DBRef.

Resources