Graph database: get common parent node - dgraph

I want to select the first common boss for two employees in draph.
My model is simple:
name: string
boss_of: uids
Lets assume the following data where each arrow denotes the boss_of edge:
A -> B
A -> C
B -> D
C -> E
E -> F
E -> G
So, given F And D the query should return A, for F and G the result is obviously E.
I tried using allofterms but found no solution as there may be a different number of nodes
between the co-workers and their common boss. Is it possible at all to formulate such a query?
I am trying to explore dgraph (or graph databases at all), so maybe I am just overseeing something.

You can use K-Shortest Path Queries
The middle one in the response is the closest common entity.

Related

Decomposing tables where some attributes aren't in any minimal, non-trivial functional dependency

While writing a library to automatically decompose a given table, I came across some special cases where the first steps of Bernstein's synthesis for 3NF (ACM 1976) give me results I don't expect.
Take this simple case:
a b
---
1 1
2 1
1 2
2 2
By my understanding, this is the full set of functional dependencies:
{} -> {}
a -> {}
a -> a
b -> {}
b -> b
ab -> {}
ab -> a
ab -> b
ab -> ab
By eye, we can see that both attributes together form a candidate key, and there's no normalisation to be done. However, suppose we take the full FD set above, and try to apply Bernstein to decompose the table. We expect to get the same table back.
Bernstein has the following first steps:
Eliminate extraneous attributes. We simplify to
{} -> {} (repeated)
a -> a (repeated)
b -> b (repeated)
ab -> ab
Find a non-redundant covering. ab -> ab is redundant by augmentation, so we have
{} -> {}
a -> a
b -> b
I'd say the latter two are redundant as well, by reflexivity. If we keep them, the remaining steps give two non-equivalent keys, which result in two separate relations after applying the rest of Bernstein synthesis. If we don't keep them, there's nothing to work with, so the remaining steps give no tables.
Where is the problem in the above?
This appears to be solved by an addendum to Bernstein's synthesis, that I came across in lecture videos from Gary Boeticcher, then at UHCL: if the decomposition does not contain a table containing one of the original table's candidate keys, then adding an additional table with one of those candidate keys will make the decomposition lossless. In this case, after applying Bernstein's synthesis, and getting no tables in return, we could add a table with both attributes a and b. This gives us back the original table, as we'd expect.

Can we represent DAG(directed acyclic graph) using PostgreSQL ltree?

I want to store hierarchical data in the PostgreSQL database.
I found ltree extension but it is used to store tree-structured data i.e there can be only one parent node.
Is there any way I can tweak it to store multiple parent nodes?
Yes, it is possible to do so using the ltree extension, by using two tables: one for your nodes and another for your paths. Bustawin has a great writeup on how to work with DAGs using this extension with this strategy.
For a node to have multiple parents, it is necessary that we define more than one ltree path for such node, one that leads from each parent. Say we have a DAG that forms a diamond between nodes A, B, C, and D:
A -> B
B -> D
A -> C
C -> D
Using the extension, you should have a node D related to two paths, A.B.D and A.C.D. Both queries should return node D
SELECT * FROM nodes
JOIN paths ON paths.node_id = nodes.id
WHERE paths.ltree_path ~ "A.B.*{1}"
SELECT * FROM nodes
JOIN paths ON paths.node_id = nodes.id
WHERE paths.ltree_path ~ "A.C.*{1}"

Simple sequence of events

Assume events of either type A, B, C or D are being emitted. I want to detect whenever an event of type A is followed by an event of type B. In other words, I want to detect a sequences, for which Esper's EPL provides the -> operator.
However, what I described above is ambiguous, what I want is the following: Whenever a B is detected, I want it to be matched with the most recent A.
I have been playing around with EPL's syntax, but the best I could come up with was that:
select * from pattern [(every a=A) -> b=B]
This, however, matches each B with the oldest A that occured after the last match. Weird...
Help is much appreciated! :P
I use joins a lot for the simple matching. The other option is match-recognize. The join like this.
select * from B unidirectional, A.std:lastevent()

How is every binary relation BCNF?

So, as part of my assignment, I have to prove that any relation with two attributes is in BCNF.
As per my understanding, if for a relation we have 3rd normal form and one non key attribute functionally determine key attribute, it violates the BCNF.
Say my relation consists of two attributes A1,A2
Scenario1(only one functional dependency)
A1 -> A2 (so A1 is the key, and A2 does not FD A1 : so no violation)
same applies for
A2 -> A1
But what if
A1->A2 and A2->A1
Here key can be either A1, A2. And the other non key attribute functionally determines the key.
In each functional dependency X -> Y, X and Y are sets of attributes. This requires special attention when either X or Y is an empty set1. So, in the example with only two attributes A1 and A2, we have all the possible non-trivial dependencies:
1. {} -> {A1}
2. {} -> {A2}
3. {} -> {A1 A2}
4. {A1} -> {A2}
5. {A2} -> {A1}
All the other possible dependencies are trivial dependencies, i.e. the right set is a subset of the left set (for instance {A1} -> {}, {} -> {}, {A1} -> {A1}, {A1 A2} -> {A1}, etc.). We know that these dependencies always hold, so they are not considered in the definition of the normal forms.
1. When empty sets are excluded from dependencies, the theorem is true
Consider the dependencies 4 and 5. We have four possible cases:
1. Only 4 holds, so we have: {A1} -> {A2}
this means that {A1} is a candidate key (since from {A1} -> {A2} we can derive that {A1}->{A1 A2}), and the BCNF condition is satisfied since each dependency has a superkey as determinant;
2. Only 5 holds, so we have: {A2} -> {A1}
equivalent to the previous case, only the role of A1 and A2 is exchanged;
3. Neither 4 nor 5 hold (no functional dependencies),
so the BCNF is formally satisfied (since no dependency violates the BCNF); and, finally:
4. both hold, so we have {A1} -> {A2} and {A2} -> {A1}
also in this case the relation is in BCNF, since {A1} and {A2} are both candidate keys, since they determine all the attributes (simply put together 1 and 2 above).
2. When we allow the empty set in the functional dependencies, the theorem is not true
Consider a relation R(A1, A2), with a cover F of the dependencies
F = { {}-> {A1} }
The meaning of {} -> {A1}, by recalling the definition of functional dependency, is that the column A1 has a constant value. So we have a relation with two columns, one of which has always the same value. In this case the only candidate key is {A2}, since {A2}+ = {A1 A2}, with {A1 A2} a superkey, and the relation is not in BCNF since a non-trivial functional dependency ({} -> {A1}) has a determinant which is not a superkey.
1 Note that in the scientific literature on the subject (as well as in books on databases) the possibility of empty sets in functional dependences is sometimes explicitly excluded (for instance, see: Tsou, Don-Min, and Patrick C. Fischer. “Decomposition of a Relation Scheme into Boyce-Codd Normal Form.” ACM SIGACT News 14, no. 3 (July 1, 1982): 23–29. https://doi.org/10.1145/990511.990513), while sometimes it is allowed, or not discussed.
For any relation to be in BCNF, the following must holds.
X → Y is a trivial functional dependency (Y ⊆ X).
X is a superkey for schema R
Wikipedia link here
For Example, there is a relation R = {A,B} with two attributes.
The only possible (non-trivial) FD's are {A}->{B} and {B}->{A}.
So, there are four possible cases:
1. No FD's holds in R. {C.K = AB}, Since it is an all key relation it's always in BCNF.
2. Only A->B holds. In this case {C.K = A} and relation satisfies BCNF.
3. Only B->A holds. In this case {C.K = B} and relation satisfies BCNF.
4. Both A->B and B->A holds. In this case there are two keys {CK = A and B} and
relation satisfies BCNF.
Hence, every Binary Relation (A relation with two attributes) is always in BCNF!
To prove any relation with two attributes is in BCNF.
Rule For Boyce-Codd Normal Form:
A relation R is in BCNF if R is in Third Normal Form and for every FD,LHS is super key
so if, A1 and A2 are the only attributes: A1 -> A2 and A2 -> A1 as functional dependencies, then in both functional dependencies, the left-hand side is a super key. Which satisfies the condition of BCNF.

Merge neo4j relationships into one while returning the result if certain condition satisfies

My use case is:
I have to return whole graph in result but the condition is
If there are more than 1 relationship in between two particular nodes in the same direction then I have to just merge it into 1 relationship. For ex: Lets say there are two nodes 'm' and 'n' and there are 3 relations in between these nodes say r1, r2, r3 (in the same direction) then when I get the result after firing cypher query I should get only 1 relation in between 'n' and 'm'.
I need to perform some operations on top of it like the resultant relation that we got from merging all the relations should contain the properties and their values that I want to retain. Actually I will retain all the properties of any one of the relations that are merging depending upon the timestamp field that is one of the properties in relation.
Note : I have same properties throughout all my relations (The number of properties and name of properties are same across all relations. Values may differ for sure)
Any help would be appreciated. Thanks in advance.
You mean something like this?
Delete all except the first
MATCH (a)-[r]->(b)
WITH a,b,type(r) as type, collect(r) as rels
FOREACH (r in rels[1..] | DELETE r)
Ordering by timestamp first
MATCH (a)-[r]->(b)
WITH a,r,b
ORDER BY r.timestamp DESC
WITH a,b,type(r) as type, collect(r) as rels
FOREACH (r in rels[1..] | DELETE r)
If you want to do all those operations virtually just on query results you'd do them in your programming language of choice.