Making a Tree like Structure in Json With Recursion - json

I'm struggling to get my head around this one, i've had a few attempts and failed miserably.
Basically I have a list of Employees in a database, each with an ID. A Employee can have a parent Employee (Refer as Manager).
I need to output the structure in some sort of tree in json format like shown in this URL
https://raw.githubusercontent.com/bumbeishvili/Assets/master/Projects/D3/Organization%20Chart/redesignedChartLongData.json
Here is a very basic structure example

The JSON can have a structure like this, containing an array of employees:
{
"employees":[
{
"id": 1764,
"name": "Maaz",
... //other fields... this employee has no parent field or
// "parent" : 0 (invalid value)
},
{
"id": 1765,
"parent": 1764,
//other fields... this employee has Maaz as parent
}
]
}
"parent" can simply be an optional field of the employee, containing theid of the parent employee.
If the json had a recursion (i.e. "parent": { /*...*/ }) this would create several issues such as:
Will the parent employee only be stored as second level, or also appear in the list as top level? This adds redundancy or alternatively, search complexity. because if 1764 only appears as child of 1765, you have to potentially recursively trasverse the whole list tree in order to find any employee.
What is the maximum depth of the recursion? With trasversal problems.
Inconsistency or circular relations, leading to loops. If A is parent of B and B is parent of A. Or if there is redundancy but upon deletion the employee does not get wiped anywhere.
More complex operations: if you have a chain of 5 parent-child employees and remove the top one, what do you do with the rest? You would have to define a policy. And adjust the tree everytime.
A flat list on the other hand required just 2 O(n) searches when you are looking for example, for employee 1765. You will then find its parent id and search the list again for an employee with than id, if it exists.
When you add an employee, add without a parent field and edit it later. When you delete an employee, just delete it and eventual broken links will be found at (flat) search time.

Related

How to make parent child schema in mongo db and retrive the data

need help to design and fetch data from MongoDB, the requirement is needed to create a category schema where each category can have multiple child categories and each child category can have further child category and so on, so if in MySQL I have designed it then I can design it like below
category table
id name parent_id
So as you can see the parent_id will be the primary key of the category id and so on, no matter how many children comes it can be handle in it, but I am not getting how to do this in mongo schema as I am new in this db and after making the schema how can I fetch the categories with there children and there children.
There are multiple ways to achieve this but to keep it simple if you want to go with embedding which is best if your category document has limited child and sub-child.
{
_id: ObjectId("507f1f77bcf86cd799439011"),
name: 'adsfa',
childCategories: [
{
_id: ObjectId("507f1f77bcf86cd799439012"),
name: 'asefda',
childCategories: [
{
_id: ObjectId("507f1f77bcf86cd799439013"),
name: 'afsd',
},
],
},
],
}
As for querying data you'll simply query for parent document _id which will return the whole document with child and all sub child categories. Please do note that this schema might not always be good for you if your child and subchild categories are expected to go on to a large number. In this case you can consider reshaping schema to make use of references. Below is the example for such scenario
{
_id: ObjectId("507f1f77bcf86cd799439011"),
name: 'Parent or child category name',
parent: ObjectId("507f1f77bcf86cd799439012"),
}
In this case you have to use lookups or populates in case of mongoose to fill the data for your parent. But again that totally depends on your use case. So I recommend you read a little about how to structure you document database and pros and cons for each approach.

JSON API identifiers for nested resources relative to parent

When one models resource relationships, the classic example give is for articles and comments. This becomes simple to model because:
articles can be uniquely identified: /articles/1
comments can be uniquely identified: /comments/2
their relationship can be provided as /articles/1/comments which would return only comments for that article
But how does one handle the case where the related resource only exists within the context of the parent?
For example, order and items:
order can be uniquely identified /orders/123
the items in that order only exist as /orders/123/items
and NOT as /items
In JSON-API the relationship object needs a "type" and "id" to specify the linkage:
"relationships": {
"links": {
"self": "http://example.com/orders/123/relationships/items",
"related": "http://example.com/orders/123/items"
},
"data": {
"type": <what goes here>,
"id": <what goes here>
}
}
The type and id for data would need to be relative to order number 123. Assuming, of course, that they don't get assigned a UUID or similar from a database because they are, in fact, a composite key. They exist primarily as a foreign key combination.
How does one handle that?
One option for the relation is to use type as order_item and id as a hash or something delimited string concatenation of the order's id and the item's id. (e.g. 123_abc). 123 I get from the order and abc I get from the item in the order.
Is there another way other than avoiding the need altogether to supply resource linkage?
Every resource must be uniquely identified by a combination of type and id according to JSON API specification:
Identification
Every resource object MUST contain an id member and a type member. The values of the id and type members MUST be strings.
Within a given API, each resource object’s type and id pair MUST identify a single, unique resource. (The set of URIs controlled by a server, or multiple servers acting as one, constitute an API.)
https://jsonapi.org/format/#document-resource-object-identification
Therefor you are not only requiring an ID for resource linkage but also to build any valid response including such a resource.
But there are no rules about how you generate that unique IDs per type. Combining an unique order ID with an unique item ID to get an unique ID per item in an order seems to be a fine approach if your data model doesn't include an ID.

Laravel 4 Eager Loading filtering and selecting only matching results

I'm trying to output the filter results with only matching elements.
I have two tables (in the real project, which will be 5), let's say companies and projects. A company may have more than one project or may not have any.
These are the relations:
/app/models/Company.php
<?php
class Company extends Eloquent {
public function projects() {
return $this->hasMany('Project','companyID');
}
protected $table = 'companies';
}
/app/models/Project.php
<?php
class Project extends Eloquent {
public function companies() {
return $this->belongsTo('Company','companyID');
}
}
What I want to do is, I want to get results of them both but only with matching parameters.
I've tried this:
return Company::with(array('projects'=>function($query){
$query->where('id',99); //project's id is 99
}))->get();
This is the output JSON
If I change the value from 99 to 1 (there is a result with products.id of 1), it changes into this:
I only want to get the second result from the second JSON i've posted.
As you can see in the second JSON (I'm using this parser to check), all companies are loaded regardless of the project, and only the rows matched have the object projects.
There will be more 'with's and I don't know how to filter only matching elements.
I also tried having() inside closure, but it's still same:
$query->having('projects.id','=',99);
Is there a way to filter only matching results (without using a loop) which the output will only include the results having the matched projects object?
Edit: Actually, 5 tables will be filtered.
companies, projects, works, users and user_works
Let's say;
"Companies" have many projects.
"Projects" have many works
"Works" have many users, also "Users" may have more than one work (pivot table user_works).
All relations are set correctly from models.
I want to do a global searching to these.
Something like: "Bring me the user id 1's works which has company id of 5 and project id of 4", but none of the fields are mandatory.
So these are also valid for searching: "Bring me everyone's works on project id of 2", or "bring me id 2's works", or "bring me all the works starting from today", "bring me the id 1's works on project 2", "Bring me this year's works done of company id 1".
Thanks in advance
Using whereHas() is the solution on my case. It filters relation and affects the results returned in the main query.
If you have the id of the project, would it make more sense to go that route? $project = Project::find(99); and then the company variables would be accessible with $project->companies->name;
It would make more sense to rename the companies() function to company() because a project will only ever belong to one.

How to update nested data from a PUT request

Suppose we have a Invoice that is saved in a draft state in a RDBMS. The invoice has three line items. A rest client gets the invoice, and modifies the line items.
GET /invoice/123
{
"InvoiceId" : "123",
"lineitems":
[
{ "id":"A", "qty":"5"},
{ "id":"B", "qty":"5"},
]
}
Assume user modifies the invoice as follows;
Changes quantity of Item A
Removes Item B.
Adds new item C.
The result is:
{
"InvoiceId" : "123",
"lineitems":
[
{ "id":"A", "qty":"10"},
{ "id":"D", "qty":"5"},
]
}
The net change is that a line has been deleted, a line has been updated, and a line has been added.
User then saves the draft invoice, which results in a PUT request.
PUT /invoice/123
What is the best strategy to update the line items on the server?
Keep in mind that deleteing all line items and creating them from scratch will loose any meta data on those lines (Created by, Created date, last modified by...)
Thanks,
The PUT method requests that the enclosed entity be stored under the supplied Request-URI.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Think of PUT as replace. The state of the resource in the PUT request should be the resulting state of the resource if it is accepted.
If you want to add/remove/update specific elements you should look into using PATCH.

Modeling variable depth inheritance in MySQL

I am working on a project where I need to have data inherit at variable depths, and then be able to return any descendants of a particular piece of data. I am working with geographical regions, so I was thinking about having a "Region" table, and have everything from "North America" to individual neighborhoods such as "Bronx". So, if someone types in "North America", they should also receive results for "Bronx" because "Bronx" is a descendant of "North America" by means of the relationship
North America->United States->New York(State)->New York(City)->Bronx
In my DB I was planning on having the Region table link back to itself with a table that specifies a parent/child relationship between Regions. Here is an example of what I would propose:
Any help would be greatly appreciated!
Do you dont need a new table. A foreign key in major table is enough.
This is my approach:
First problem, design data schema: I keep hierarchis with a foreign key to parent row. It is simply. You have an example with hiererchy regions here:
WOE_ID ISO Name Language PlaceType Parent_ID
20069843 "NA" "Oshana" ENG State 23424987
55921113 "NA" "Ondangwa" ENG County 20069843
...
Second problem, retrieve ascendants/descendants: As you explain, problems comes with select: select some region and all descendants os ascendants. To solve this you should to create a new tree table. This table contains pairs: al combination to a person with all they ancestors (and itself):
region( id, name, id_parent)
region_tree( id, id_ancestor, distance )
Noticie that with this structure is easy to query hierarchies. Sample: all descendants of some region:
select region.*, distance
from
region p
inner join
region_tree t
on ( p.id = t.id)
where
id_ancesor = **someregion.id **
You can play with distance to get only sub-regions, sub-sub-regions, ...
Last problem, keep tree: tree must be all time up to data. You should automatize this: a trigger over region or a store procedure for CRUD operations,