how to model many to many relation using google's firestore - nosql

I have being reading the docs about Cloud firestore Data Model
and about Security in Cloud firestore but was unable to find an answer on how to model my data.
I have groups and users and I want to implement a membership relation such that each user can be member in multiple groups and each group could obviously have multiple members.
I want to be able to efficiently be able to tell who are the members of each group and what groups a given user belongs to.
In a relational DB I would have 3 tables, users, groups and user_groups or group_membrs and I am guessing anyone reading this Q could tell how to handle this.
What collections / documents / sub collections should I use to implement the same using firestore?
I am especially concerned with the security setting that would allow a user to remove himself (and only himself) from a group and would allow a group owner/manager to add any user to the group he manages (and only to that group)
Can/Should this be implemented using only collections for users and groups with the memebrship being part of the document data on those collections? or should an additional memeber ship collection be used?

My initial take would be to do this fairly similar to how I recommended modeling many-to-many relationship on the Firebase Realtime Database. The biggest difference with your relational experience, is that you'll typically store the relations in both directions. So in addition to user_groups you'll also have group_users for a total of four collections per entity pair.

Related

Firestore, should I use a single collection for all users, or rather create a different collection for each user role?

My app should manage different users, of different roles (user / moderator / admin etc.) in Firebase Firestore.
What are the pros and cons of each approach:
A single collection for all users, where each document includes a ROLE field (user / moderator / admin etc.)
A separate collection for all users of the same role (users collections / moderators collection / admins collections etc.). Three collection in this example
One drawback for approach 2, is that authentication becomes a bit complicated since I have to look for the userId in three different collections (vs a single one in approach 1).
Are there any significant advantages to approach 2?
If you never need to search across all three collections (so if you don't need a collection group index) then having multiple collections will give you better total write performance.
If you do need to search across collections, then the write performance will be the same.
For query performance it makes no different either way, as the performance for queries on Firestore is not dependent on the number of documents in the collection/collection group.

Collection or documents for multiple projects?

I want to manage multiple projects data in mongoDB. Each project contains multiple users from multiple departments with multiple role assigned to them. plus certain task is assigned to each user. Now I am confused about schema, not able to decide which entity should be kept as collection & which one as document ? What is the best efficient way to store ?
should I keep all under single collection as embedded documents or in separate collection ?
Thanks
First of all if you are using mongodb you should know why are you using it. MongoDB is not about normalize stuff. If you are able to create data structure is de-normalize way then and only then go for MongoDB.
I think you should maintain one single document containing all the mentioned things above. But the scenario which you have mentioned above is good for relational database. you need only 3 entities in relational database and your problem is solved.
Still if you want to go for mongodb you can go with one collection only. which contains project details number of users working there and their roles and department.

How to model mongodb for custom user data

I'm developing a cms using MongoDb and am trying to get some modelling advice. It's multi-tenant and each tenant can create their own schema and choose what custom fields they want searchable/indexed. The only thing I'm waffling on is how to model my collections. It seems to me like it would be ideal for each tenant to have their own collection due to indexing, but I am not very experienced with MongoDb and would love to hear if that's even a valid statement or not.
I'm thinking about separating each tenant's schema definitions from their data - perhaps a customSchema and customData collection for each tenant. Maybe something like customSchema_5543e1191a85d8946f0ee6fc and customData_5543e1191a85d8946f0ee6fc? The major question here being how many collections are feasible in MongoDb. I'm not clear if there's a cap with the new WiredTiger or not. If not, would such a large number of collections have any downsides?
Or, is it better to have just two collections with all tenant's data in them, along with all of their individual indexes? What are the pros and cons of this approach?
Any thoughts or suggestions are welcome, particularly if anyone has had experience doing something like this before.
Update:
My use case is a cms where tenants can specify their own data, like in Sharepoint or Expression Engine, or most other content apis, like contentful or CloudCMS. A user can say, "I want to store Products, and each product has a Name, Description, Quantity, and a price". Another user could say, "I want to store bands, and each band has a Name, a HomeCity, and a whatever." The users would then want to retrieve and display that data on their pages however they like. It's a basic cms scenario where tenants can create their own schema, then create, edit, and retrieve entries of those schemas. Tenants would need to be able to denote which fields they can search on, so this highly customizable indexing per tenant is the primary area of focus and concern in the modelling strategy.
I'm waffling between two big collections to store schemas and data, shared by all tenants, and a pair of those collections for every tenant. I just don't know the pros and cons of each of those solutions in MongoDb. I'm also open to any ideas I haven't thought of yet :)

possible mongo architecture for SaaS

I'm creating a platform where customers (users) are from different organisations. So I would like to keep their data totally separated according to organisations they belong. How would you suggest to store such data in mongo db? On which level?
Are you keeping the data separate for security reasons (i.e. compliance or regulation) or simply for administration/ease-of-use?
If it's the former, I'd go with separate databases at the very least, if not separate MongoDB instances. Separate instances enables you to perform segregation at an IP level through something like iptables so that you can tie down different instances to different IP ranges, representing the different organisations presuming they will be accessing the data.
If it's the latter, I'd still go with separate databases because it gives you the ability to have different users on a database level and from version 2.2, concurrency will be on a database level (so there's no sharing of the write lock, for example, that you'd have if you split it out on collection level).
As a FYI, here's some additional information on schema design in MongoDB -
Schema Design
Schema Design Presentation by Kyle Banker
Schema Design Blogs from Customers
MongoSF2012: mongodb-schema-design-insights-and-tradeoffs
There was actually a schema introduction webinar held last week that you can now listen to.
You can create a document for each organization and put the user's details into sub-documents inside the root document.
If the overall users' profiles are so big that don't fit into MongoDB document size (16 mg), then you can use different approach by creating a document for every user and add a field referring to the organization.

MongoDB Schema Design ordering service

I have the following objects Company, User and Order (contains orderlines). User's place orders with 1 or more orderlines and these relate to a Company. The time period for which orders can be placed for this Company is only a week.
What I'm not sure on is where to place the orders array, should it be a collection of it's own containing a link to the User and a link to the Company or should it sit under the Company or finally should the orders be sat under the User.
Numbers wise I need to plan for 50k+ in orders.
Queries wise, I'll probably be looking at Orders by Company mainly but I would need to find an Order by Company based for a specific user.
1) For folks coming from the SQL world (such as myself) one of the hardest learn about MongoDB is the new style of schema design. In the SQL world, everything goes into third normal form. Folks come to think that there is a single right way to design their schema, because there typically is one.
In the MongoDB world, there is no one best schema design. More accurately, in MongoDB schema design depends on how the application is going to access the data.
2) Here are the key questions that you need to have answered in order to design a good schema for MongoDB:
How much data do you have?
What are your most common operations? Will you be mostly inserting new data, updating existing data, or doing queries?
What are your most common queries?
How many I/O operations do you expect per second?
What you're talking about here is modeling Many-to-One relationships:
Company -> User
User -> Order
Order -> Order Lines
Company -> Order
Using SQL you would create a pair of master/detail tables with a primary key/foreign key relationship. In MongoDB, you have a number of choices: you can embed the data, you can create a linked relationship, you can duplicate and denormalize the data, or you can use a hybrid approach.
The correct approach would depend on a lot of details about the use case of your application, many of which you haven't provided.
3) This is my best guess - and it's only a guess - as to a good schema for you.
a) Have separate collections for Users, Companies, and Orders
If you're looking at 50k+ orders, there are too many to embed in a single document. Having them as a separate collection will allow you to reference them from both the Company and the User documents.
b) Have an array of references to the Order documents in both the Company and the User documents. This makes the query "Find all Orders for this Company" a single-document query
c) If your query pattern supports it, you might also have a duplicate link from Orders back to the owning Company and/or User.
d) Assuming that the order lines are unique to the individual Order, you would embed the Order Lines in an array within the Order documents.
e) If your order lines refer back to individual Products, you might want to have a separate Product collection, and include a reference to the Product document in the order line sub-document
4) Here are some good general references on MongoDB schema design.
MongoDB presentations:
http://www.10gen.com/presentations/mongosf2011/schemabasics
http://www.10gen.com/presentations/mongosv-2011/schema-design-by-example
http://www.10gen.com/presentations/mongosf2011/schemascale
Here are a couple of books about MongoDB schema design that I think you would find useful:
http://www.manning.com/banker/ (MongoDB in Action)
http://shop.oreilly.com/product/0636920018391.do
Here are some sample schema designs:
http://docs.mongodb.org/manual/use-cases/
Note that the "MongoDB in Action" book includes a sample schema for an e-commerce application, which is very similar to what you're trying to build -- I recommend you check it out.