Finding an edge by unique ID or name - graph

It is possible to search a subgraph and node by their unique names;
n = agnode(g, "myUniqueNodeName", FALSE);
h = agsubg(g, "myUniqueSubgrahName", FALSE);
Likewise, is there a way to search edges in a strict directed graph by their unique names?
e = agedge (g, u, v, "e28", FALSE);
Documentation indicates that:
The 'name' of an edge (more correctly, identifier) is treated as a
unique indentifier for edges between a particular node pair. That is,
there can only be at most one edge with name e28 between any given u
and v, but there can be many other edges between other nodes.
It seems that there must be a list of edges that can be searched by name. Otherwise, a separate (ID -> edge) map will need to be maintained separately.

Related

Neo4j Creating relationship between nodes that already map to a relationship

Currently, I have a query in Neo4j that returns all the nodes in my graph that are pointed to by multiple nodes.
The query to return these nodes (in picture) looks like this:
MATCH (n)-[r:CLINICAL_SIGNIFICANCE]->()
WITH n, count(r) as rel_cnt
WHERE rel_cnt > 1
MATCH (c)-[r:PROTEIN_CHANGE]->(n)
return c, n
Is there a way to loop through the nodes labeled as c (blue nodes) and if they point to the same node labeled as n (yellow nodes), create a relationship between the nodes labeled as c (blue nodes)?

Get all childs of a particular node till a particular depth

I have this relationship in my neo4j:
Parent -> Childs
F -> D,E
D -> A,B,C
A -> X
Use case: I am trying to get all child of a particular node using this query till a particular depth let's say depth = 2
Query to get All child of node F
MATCH (p:Person)-[:REPORTS_TO *]->(c:Person) WHERE p.name="F"
WITH COLLECT (c) + p AS all
UNWIND all as p MATCH (p)-[:REPORTS_TO]-(c)
RETURN p,c;
This returns me this: (which is all child's node of F without limit)
But when I try to get all childs till depth 2 :
Query to get All child of node F with depth = 2
MATCH (p:Person)-[:REPORTS_TO *2]->(c:Person) WHERE p.name="F"
WITH COLLECT (c) + p AS all
UNWIND all as p MATCH (p)-[:REPORTS_TO]->(c)
RETURN p,c;
Which returns
When I put depth = 2, it didn't return all child's of D' (only returned A and notB`, 'C')
Expected response was:
All child's of 'F', child's of all child's of `F' (i.e level 1) and child's of all childs of nodes of level 1 (i.e level 2)
Am I missing something in my query or any another way to get a response as I expected above?
Adding dataset
CREATE (f:Person {name: "F"})
CREATE (e:Person {name: "E"})
CREATE (d:Person {name: "D"})
CREATE (c:Person {name: "C"})
CREATE (b:Person {name: "B"})
CREATE (a:Person {name: "A"})
CREATE (x:Person {name: "X"})
CREATE (a)-[:REPORTS_TO]->(x)
CREATE (d)-[:REPORTS_TO]->(a)
CREATE (d)-[:REPORTS_TO]->(b)
CREATE (d)-[:REPORTS_TO]->(c)
CREATE (f)-[:REPORTS_TO]->(d)
CREATE (f)-[:REPORTS_TO]->(e)
The problem is you're not querying for what you think you're querying for.
[:REPORTS_TO *2]
doesn't query up to depth 2, it queries nodes at exactly depth 2. The result is nodes B, C, A, and F (since you added it in).
Of those nodes, only nodes A and F have an outgoing :REPORTS_TO relationship, so your match eliminates B and C from the result set. The nodes returned are A and F and the nodes reachable by an outgoing :REPORTS_TO relationship (E, D, and X).
If you want to alter your query so it's up to depth 2 instead of exactly depth 2, use a range on the variable-length relationship (omitting the lower-bound makes it default to 1):
[:REPORTS_TO *..2]
And if you want this to include F in the match itself (instead of manually adding it when you collect the nodes), use a lower bound of 0:
[:REPORTS_TO *0..2]

igraph: get and permute vertex ids

In R package igrpah, how are ids assigned to each vertex? Is there a similar function like get.edge.ids that we can get vertex id from a vertex, e.g. g = graph.ring(3); V(g)$name=LETTERS[1:3], so get.vertex.ids(V(g)['A']) will return the id of the vertex 'A', which is 1 in this example. And how can we change the id of the vertices? Sure we cannot change the id of only one node, but can we permute the vertex ids?
Use permute.vertices() to permute the IDs of the vertices. Note that the vertex IDs are always integers between 1 and |V| in R (where |V| is the number of vertices).

Query ArangoDB general-graph for common neighbors with more than 2 start vertices?

Consider the following example graph:
 
Given the vertices A, B and C (creators), how to figure out their common neighbors?(projects all 3 participated in)For two vertices, I could simply use GRAPH_COMMON_NEIGHBORS("myGraph", A, B), but what if I want to query for 3 or more? Expected result: 1 and 2.
Given the same vertices, how can I make it return common neighbors with no other connections?(creators exclusively participated in a project, no additional edges allowed)?Expected result: 1, because 2 has an edge coming from D, which isn't one of the starting vertices.
You can simply pass the same set of vertices as both parameters for common neighbors. Then repack the result in a better format for AQL to compute the intersection:
let res = (
let nodes = ["a/A","a/B","a/C"]
for n in GRAPH_COMMON_NEIGHBORS("g",nodes , nodes)
for f in VALUES(n)
return VALUES(f)
)
return CALL("intersection", res[0])

Finding Subgraph in a Graph

I have a graph shown here. Just to node that nodes B_0, B_1, belong to node of type B, C_0, C_1. C_2, C_3 belong to node of type C and so on.
Now, I want to find multiple subgraphs, which could satify criteria like defined by this example -
Criteria -
subgraph contains 1 node of type A, 1 node of type B, 1 node of type C, one node of type D.
subgraph has one edge from node of type A to one node of type B, one edge connecting type B and type C and one node connecting type C and type D.
subgraph contains one edge from type A going out of subgraph to type B node, one edge
from type B to type C node outside, one edge from type D to type E outside.
Now this description should give result as -
subgraph :: A_0, B_0, C_1, D_1
subgraph :: A_0, B_0, C_0, D_0
subgraph :: A_0, B_1, C_2, D_2
subgraph :: A_0, B_1, C_3, D_3
I want to know, if there is any algorithm, by which I can find such sub-graphs?
I tried to figure out an algorithm by making all possible combinations. However, this would be exponential to number of nodes in subgraph. Thus, I want to know if there exists an efficient way to calculate it. Or if there exists a problem of similar nature in Graph Theory?
You can start by visiting all nodes of type A. For each A node, look at all nodes connected to it which are of type B. From there look all nodes of type C and so on, keeping track of the nodes you've visited from the last A node. Then whenever you reach a subnode that completes the criteria of your search, you add all the list of nodes from the A node until the point where you are. Essentially you're doing a depth-first search where you keep traversing into the graph as long as a node meets the criteria of what should follow and backtrack whenever there's no more valid nodes (ie. which would produce a valid subgraph) going out from your current node.

Resources