Suppose I have following 4 collections:
1- posts
2- companies
3- groups
4- users
Bellow is my current structure in post:
and their relation is:
A company has an owner and many other members (user collection).
A group has many members (users).
A user has many posts.
A group has many posts that published by one of its members.
A company has many posts that published by its owner or members.
Now i have a problem on storing relation of users, company, and group with posts collection.
Bellow is my current structure:
I have decided to have a field postable inside my post document, and has a type field that will be 'user', or 'group', or 'company', and two other fields name, and id that will be company/group id and company/group name in cases that post is belonged to company or group but not user means type="group" || type="company".
Now how i can handle this to map id as FK of group and company collection (one field FK of two collection) ?
Is it the right structure ?
What you have here is a polymorphic association. In relational databases, it is commonly implemented with two fields, postable_id and postable_type. The type column defines which table to query and id column determines the record.
You can do the same in mongodb (in fact, that is what you came up with, minus the naming convention). But mongodb has a special field type precisely for this type of situations: DBRef. Basically, it's an upgraded id field. It carries not only the id, but also collection name (and database name).
how i can handle this to map id as FK of group and company collection (one field FK of two collection)?
Considering that mongodb doesn't have joins and you have to load all references manually, I don't see how this is any different from a regular FK field. Just the collection name is stored in the type field now, instead of being hardcoded.
Related
So in a traditional database I might have 2 tables like users, company
id
username
companyid
email
1
j23
1
something#gmail.com
2
fj222
1
james#aol.com
id
ownerid
company_name
1
1
A Really boring company
This is to say that user 1 and 2 are apart of company 1 (a really boring company) and user 1 is the owner of this company.
I could easily issue an update statement in MySQL or Postgresql to update the company name.
But how could I model the same data from a NoSQL perspective, in something like Dynamodb or Mongodb?
Would each user record (document in NoSQL) contain the same company table data (id, ownerid (or is owner true/false, and company name)? I'm unclear how to update the record for all users containing this data then if the company name needed to be updated.
In case you want to save the company object as JSON in each field (for performance reasons), indeed, you have to update a lot of rows.
But best way to achieve this is to have a similar structure as you have above, in MySQL. NoSql schema depends a lot on the queries you will be making.
For example, the schema above is great for:
Find a particular user by username, along with his company name. First you need to query User by username (you can add an index), get the companyId and do another query on Company to fetch the name.
Let's assume company name changes often
In this case company name update is easy. To execute the read query, you need 2 queries to get your result (but they should execute fast)
Embedded company JSON would work better for:
Find all users from a specific city and show their company name
Let's assume company name changes very rarely
In this case, we can't use the "relational" approach, because we will do 1 query to fetch Users by city and then another query for all users found to fetch the company name
Using embedded approach, we need only 1 query
To update a company name, a full (expensive) scan is needed, but should be ok if done rarely
What if company name changes ofter and I want to get users by city?
This becomes tricky, NoSQL is not a replacement for SQL, it has it's shortcomings. Solution may be a platform dependent feature (from mongo, dynamodb, firestore etc.), an additional layer above (elasticSearch) or no solution at all (consider not using key-value NoSQL)
Depends on the programming language used to handle NoSQL objects/documents you have variety of ORM libraries to model your schema. Eg. for MongoDB plus JS/Typescript I recommend Mongoose and its subdocuments. Here is more about it:
https://mongoosejs.com/docs/subdocs.html
I am currently trying to model a MongoDB database structure where the entities are very complex in relation to each other.
In my current collections, MongoDB queries are difficult or impossible to put into a single aggregation. Incidentally, I'm not a database specialist and have been working with MongoDB for only about half a year.
To keep it as simple as possible but necessary, this is my challenge:
I have newspaper articles that contain simple keywords, works (oevres, books, movies), persons and linked combinations of works and persons. In addition, the same people appear under different names in different articles.
Later, on the person view I want to show the following:
the links of the person with name and work and the respective articles
the articles in which the person appears without a work (by name)
the other keywords that are still in the article
In my structure I want to avoid that entities such as people occur multiple times. So these are my current collections:
Article
id
title
keywordRelations
KeywordRelation
id
type (single or combination)
simpleKeywordId (optional)
personNameConnectionIds (optional)
workIds (optional)
SimpleKeyword
id
value
PersonNameConnection
id
personId
nameInArticleId
Person
id
firstname
lastname
NameInArticle
id
name
type (e.g. abbreviation, synonyme)
Work
id
title
To meet the requirements, I would always have to create queries that range over 3 to 4 tables. Is that possible and useful with MongoDB?
Or is there an easier way and structure to achieve that?
Is it possible to reference additional columns apart from the 'Code' and 'Name' columns when using a domain attribute in an entity?
E.g. A person entity has a code of '1' and a name of 'Smith' and a Gender of 'Male'
In a customer entity there is a domain value referencing the person entity which displays the following 1 {Smith}. The users would like an additional read only attribute which would copy the Gender value of 'Male' into the customer entity based on the domain value. Can this be done using out of the box MDS UI?
I know this is duplicate data and breaks normal form but for usability this would be useful. It would be the equivalent of referencing additional columns in an MS Access drop down list.
Many thanks in advance for any help
This is not possible with the standard UI. One option would be to develop a custom UI where you can handle these kind of requests.
If you want to stick with the standard product I can see a workaround but this is a bit of a "dirty" one.
You can misuse (abuse) the Name attribute of the Person entity by adding a business rule to the Person entity that generates the content of the Name attribute as a concatenation of multiple attributes. You of course need an additional attribute that serves as a place holder for the original Name. The concatenated field will then show in your customer entity.
One question that does come to mind is why a user would like/need to see the gender of a person in a customer list? As you have a separate Person entity I expect you to have multiple persons per customers. What would the gender of one person - even if it is the main contact - matter?
I am new to odoo v8 and i am not able to understand the relationship between res_partner and res_users tables and also with hr_employee table are they all related?
The relationship between res.partner and res.user is that res.user inherits from res.partner using an inheritance type called "Delegation Inheritance" (see documentation).
Because of "Delegation Inheritance" every res.user record has a mandatory internal connection to a corresponding res.partner record using a field partner_id. What is this connection all about is to directly use all the fields of res.partner to store data shared by res.user and res.partner (i.e. name, phone, etc... if for example you refer to phone property of a record of res.user you'll get the value stored in the corresponding res.partner record) so res.user has to define fewer number of fields on it's own, like password, login, etc..
Note also that because of this relation res.user can NOT exist in the system without corresponding res.partner, it's why every res.user has one, but nonetheless res.partner can exist without res.user.
hr.employee have m21 with res.users (user_id)
res.users have m21 with res.partner(partner_id)
Actually only res.users has a "real" relationship to res.partner, because with every user odoo will create a partner (per default no customer and no supplier). this partner will be used e.g. for emails and the followers system in odoo.
But you can have partners without users, too. That will be a normal partner, for defining customers and suppliers.
And finally there is the employee. You can set a user on it. If i recall right, the user will be used for attendances and timesheets.
I am trying to come up with a MongoDB document model and would like others opinions. I want to have a Document that represents an Employee. This table will contain all attributes of an employee (I.e. firstName, LastName). Now where I am stuck coming from the relational realm, is the need to store a list of employees an employee can access. In other words lets say Employee A is a Manager. I need to store the direct reports that he manages, in order to use this in various applications. In relational I would have a mapping table that tied an employee to many employees. In mongo not being able join documents, do you think I should utilize an embeded (sub-document) to store the list of accessible employees as part of the Employee document? Any other ideas ?
Unless your using employee groups (Accounting, HR, etc) You'll probably be fine adding the employee name, mongo Object ID, and any other information unique to that manager / employee relationship as a sub document to the managers document.
With that in place you could probably do your reporting on these relationships through a simple aggregation.
This is all IMHO, and begs the question; Is simple aggregation another oxymoron like military intelligence?