This module is a collection relationship manager, lets you specify linking information between collections, gives you ability to easily manipulate these links (like add, remove), and provides an easy way to fetch them.
In addition to that, you also have the ability create resolver links that can make REST-API calls or link with any type of database.
When linking MongoDB collections, we support 4 different ways:
We use this when we want to reference a single Document. For example, a comment has one author. Or a post has one author.
We use this when we want to store multiple references to a collection. This can be viewed as a Many-To-Many SQL relationship, but not necessarily. For example, a user may belong in multiple groups:
Meta comes from metadata. This is used when we want to store additional information about the link. For example, if a user belongs to a single group, we want to store the fact that he is an Admin or not.
This relationship can be emulated in different ways. We could also store via a Many relationship “adminIds” at Group Level. There is no right or wrong. Just choose what’s best fit.
Same as the scenario in One Meta, but in this case, a user can belong to multiple groups and he can be admin only to some.
To emulate that you can also have done it in Group Document:
You have a Comment that is posted by an User. We either store userId at Comment level, or store commentIds at User level. The second one doesn’t make much sense, so we’ll explore the first one.
If we store “userId” in Comment document. We have a “One” relationship.
To create this kind of link we would do:
We will use the getLink method, which is an object that allows us to fetch, and modify the linked elements.
Removing/unsetting the link, will not affect the related document. If you want to remove it from the database, you will have to do it manually.
All good but I may want at the user level to fetch all my comments I posted. This is where we introduce the concept of inversed links. An inversed link basically means that the information about the link is stored on the other side. In our case, in the Comment document.
If you use filters when fetching from a link, the filters will be applied only for the linked documents.
Now, let’s continue our journey and assume the comment might have different tags. So let’s use a Many relationship:
Keep in mind: For single relationships One and One Meta we use set() and unset(). For many relationships Many and Many Meta we use add() and remove().
A meta relationship is very useful because you may need to store information about the relationship. Such as an user can belong to certain groups, but he is an admin only to some group
So instead of creating a separate collection for this, or poluting the groups document, we could use meta relationships.
The same principles apply to One Meta relationships, but you don’t need to specify the _id:
Given a relationship between 2 entities: Users and Groups
You can now fetch only the groups you are admin to like this:
It also works from the inversed side as well:
Meta filters also works with Query
Reference the same collection in the link. For tree-like database structures this is great.
You must use a sync function for this to work. Read more about Meteor.wrapAsync.
You can also use resolver for special database queries for example, you may need to get only the messages that he has not seen yet.
It is very likely that you would use SimpleSchema to ensure a data-structure for your documents, and prevent bad data to be inserted. This library automatically detects whether you have a schema attached to your collection or not, and will add fields with proper schema definitions.
IMPORTANT! In order for this to work without problems, make sure your schema is attached before defining links. These are the appended schemas by link type.
For meta relationships, it creates a blackbox schema if the metadata option contains no keys
This will append to your schema:
This will append to your schema:
_id field is put by default.
If you have a many meta relationship:
Appended schema will look like:
Let’s say I have a “Thread” with multiple “Members”. If a “Member” is deleted from the database, we don’t want to keep unexisting references. This is why if we delete a member, thread document should be cleaned.
This works for any kind of relationship.
This is achieved by using https://atmospherejs.com/matb33/collection-hooks package. And it only works if Member contains the inversed link to Thread.
Let’s see how that works’
When Member is removed from the database, it will look for all the threads of that member. And it will remove it from the fieldStorage. This way your data will be consistent without having to deal with it.
Be careful with this one! When Member document is deleted, all posts will be deleted.
This works from direct and inversed side as well. Use with caution.
By using index: true option, it will call _ensureIndex automatically on your collection. This will give you a performance boost when you are searching from the “related” link, in our case, from “Posts”.