I'm pretty new with NoSQL, MongoDB. How to deal with the many-to-many relation between 2 or multiple collections/documents? we'd better use DBRefs or embed? actually I've already read the MongoDB manual, but I didn't find something about many-to-many relation. I missed some points? or there is no this kind of relation in MongoDB? thx!
Embed versus reference
This is the problem of embedding versus referencing, and it’s a common source of confusion for new users of MongoDB. There’s a simple rule of thumb that works for most schema design scenarios: Embed when the child objects always appear in the context of their parent. Otherwise, store the child objects in a separate collection.
Embed or reference it depends on the application. Suppose you’re building a simple application in MongoDB that stores blog posts and comments.If the comments always appear within a blog post, and if they don’t need to be ordered in arbitrary ways (by post date, comment rank, and so on), then embedding is fine. But if, say, you want to be able to display the most recent comments, regardless of which post they appear on, then you’ll want to reference. Embedding may provide a slight performance advantage, but referencing is far more flexible.
Many-to-many
In RDBMSs, you use a join table to represent many-to-many relationships; in MongoDB, you use array keys. For example each product contains an array of category IDs, and both products and categories get their own collections. If you have two simple category documents
{ _id: ObjectId("4d6574baa6b804ea563c132a"),
title: "Epiphytes"
}
{ _id: ObjectId("4d6574baa6b804ea563c459d"),
title: "Greenhouse flowers"
}
then a product belonging to both categories will look like this:
{ _id: ObjectId("4d6574baa6b804ea563ca982"),
name: "Dragon Orchid",
category_ids: [ ObjectId("4d6574baa6b804ea563c132a"),
ObjectId("4d6574baa6b804ea563c459d") ]
}
Related
We have a collection of documents, each document has an array of objects
{
"_id":_MONGO_ID_,
"property":"value",
"list":[{...}, {...}, ...]
}
But each object of the list also needs a unique id for the needs of our app.
{"id":213456789, "somestuff":"somevlue" ...}
We do not wish to create a collection for these objects because they are small and would rather store them straight into the document.
Now the question. Right now we generate a unique id based on time which looks like the MongoID. We need an id to make it easier to target each object. Would it be a good idea to generate a MongoID for each object of the list instead? Any pros and cons?
In general, it is wise to separate DB-specific resources from business/data domain resources. You always want to be able to manipulate the data completely independent of the host database and the drivers associated therewith. ObjectId() is relatively lightweight and in fact a BSON type, separate from the MongoDB core objects, but for true arms-length separation and an easier physical implementation, I would recommend a simple string instead. If you don't have extreme space/scale issues, UUIDv4 is good way to get a unique string.
I am new to MongoDB moving in from traditional SQL relational approach. I am working on a simple “Category has many Products” scenario (c#.Net). Where Category has
List<Product>
My questions are.
Question 1: On Add Product screen I have a drop down for Categories. So on Submit should I
First Insert Product in Products Collection and then
Push this Product in Nested Product of Categories collection.
_categoryCollection.Update(id, Update< Category>.Push…)
Question 2:
Or
We shouldn’t just have anything called “Product Collection”. Instead we should have only one Categories collection with Nested Products in it. And on submit just Push this new Product in respective Category.
Question 2.1 : What if we want to do this association for product with category after the product is added. ?
Or
Question 3:
Considering question one. Should we have CategoryId in Product entity ? does this makes any sense in No SQL concepts ?
I've always found this MongoDB article a good resource for such questions.
http://docs.mongodb.org/ecosystem/use-cases/product-catalog/
The questions you need to ask are, how will the data be accessed? What are my objects and how are they formed? Start with your programming first, create your classes (domain objects) and your access patterns, then worry about Mongo. You'll see, Mongo won't really get in your way. That is what is was meant to do.
So, going back to your scenario. If you know the categories are going to be big in number, need to be tightly controlled and manipulated often, then you could have a second collection for them and reference back to that collection's _id field in your category field in the product documents. Important is, the values themselves for the categories should be stored with each product document, in order to have fast reads due to one less query or the need to join the data.
Scott
A few considerations can be made here:
If a category has many products but a product cannot belong to more than one category, then
If number of products is not expected to be very large per category, then
Nest products inside category document
Else, use a different collection for products and use field 'categoryId' in them
Else, use use a different collection for products and use field 'categoryId' in them
Nest documents only when they have one definite parent and they are not huge or too many. Otherwise, the parent document will get huge with no way to control its size.
Let's say I'm making a social app with MongoDB database, and I want users to be able befriend each other. Of course friendship is a mutual relation and user ids are integers. What would be the best approach?
Every user has a list of friend ids. Every time a bond is created/severed, both users' lists have to be updated.
Create join table 'friendship' containing IDs of 2 users. Every time bond is created I have to create two entries. 1->2 and 2->1
As no. 2, but always create only 1 bond with rule: lower_usr_id -> higher_usr_id. Assuming there are a lot of people and friendships. Wouldn't it save a lot of space and time?
It sounds like you're rather unclear about how MongoDB works. Joins aren't something that appears in MongoDB, and if you're trying to use MongoDB like a relational database you're doing it wrong.
I'm no expert on MongoDB, but I believe there are two common methods of modelling a one-to-many relationship:
Embedding one document inside another
Using references
Embedding a document inside another makes sense where the parent document in some sense "owns" the child document. For instance, in the context of a blogging application, a comment is owned by a post, so it might make sense to embed the comment inside the post.
For your use case, I don't believe that would be appropriate since the relationship is between objects of the same type. It would therefore make sense to record friendships as a reference to another object in the same collection.
Check out this link for further details.
I have two tables/collections; Users and Groups. A user can be a member of any number of groups and a user can also be an owner of any number of groups. In a relational database I'd probably have a third table called UserGroups with a UserID column, a GroupID column and an IsOwner column.
I'm using MongoDB and I'm sure there is a different approach for this kind of relationship in a document database. Should I embed the list of groups and groups-as-owner inside the Users table as two arrays of ObjectIDs? Should I also store the list of members and owners in the Groups table as two arrays, effectively mirroring the relationship causing a duplication of relationship information?
Or is a bridging UserGroups table a legitimate concept in document databases for many to many relationships?
Thanks
What I've seen done, and what I currently use are embedded arrays with node id's in each document.
So document user1 has property groups: [id1,id2]
And document group1 has property users: [user1]. Document group2 also has property users: [user1].
This way you get a Group object and easily select all related users, and the same for the User.
This takes a bit more work when creating and updating the object. When you say 2 objects are related, you have to update both objects.
There's also a concept DBReferences in MongoDB and depending on your driver, it'll pull referenced objects automatically when retrieving a document.
http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef
In-case anyone interested, I just bumped into a very good article posted in mongoDB blog. 6 Rules of Thumb for MongoDB Schema Design. There are 3 parts in this article, after reading all 3 you'll have a good understanding.
Let's understand Many to Many Relations with an examples
books to authors
students to teachers
The books to authors is a few to few relationship, so we can have either an array of books or authors inside another's document. Same goes for students to teachers. We could also embed at the risk of duplication. However this will required that each student has a teacher in the system before insertion and vice versa. The application logic may always not allow it. In other words, the parent object must exist for the child object to exist.
But when you have many to many relationship, use two collections and have a true linking.
I'm trying to implement blog post storage using mongo db.
I've got two domain entities:
"Blog post" and "Author"
Currently I've added AuthorId property to blog post entity. Is that the right approach to store relation between objects?
I think this post will be right for you http://www.mongodb.org/display/DOCS/Schema+Design
Use Cases
Customer / Order / Order Line-Item
Orders should be a collection. customers a collection. line-items should be an array of line-items embedded in the order object.
Blogging system.
Posts should be a collection. post author might be a separate collection, or simply a field within posts if only an email address. comments should be embedded objects within a post for performance.
Schema Design Basics
Kyle Banker, 10gen
http://www.10gen.com/presentation/mongosf2011/schemabasics
Indexing & Query Optimization
Alvin Richards, Senior Director of Enterprise Engineering
http://www.10gen.com/presentation/mongosf-2011/mongodb-indexing-query-optimization
**These 2 videos are the bests on mongoddb ever seen imho*
Currently I've added AuthorId property to blog post entity. Is that the right approach to store relation between objects?
I'd say no. You are "supposed" to store everything you need in a blog document in a denormalized way (e.g. the blog post, the comments, the tags, etc). So if you want to show the Author's name, you should add it to the blog document. This would allow to fetch an entire page's data with a single query, which is kinda the point of a document-oriented database.