Neo4j displaying path of a hiearchy, and select the depth of hierarchy to display - neo4j

My first Neo4j question - so gentle please
Here is some ascii art of what I want to show
1 - I have 2 nodes, Node 1 and Node 5, where Node1 has OUTPUTS relationship to Node3 and Node3 OUTPUTS to node 5
2 - In the case of Node 3, it is decomposed into Nodes 2,3 and 4, where
Node 2 and Node 4 are CHILD of Node 3.
I want to be able to selectively show a path that has the parent node only
PATH A below
OR
where I want to include the child nodes as well, PATH B
PATH A
node1 -[:OUTPUT]-> node3 - [:INPUT]-> node5
|
-----[CHILD]---- -------[CHILD]-----
| |
| |
node1-[:OUTPUT]->node2-[:INPUT]->node3-[OUTPUT]->node4-[INPUT]-> node5
PATH B
thanks all

Related

Check node is only neighbor node or a child node

Is it possible to check? If node 2 gets DIO from node 3, then node 2 checks whether node 3 is only a neighbor node or it is a child node of node 2.

Merge two sub graphs in neo4j

I have two subgraphs in the following way
(root1) (root2)
/ | \ / | \
/ | \ / | \
/ | \ / | \
(a1) (a2) (a3) (b1) (b2) (b3)
I want to create a new graph by merging above two
(root)
/ / / \ \ \
(a1)(a2)(a3)(b1)(b2)(b3)
Is there a way to just replace one of the root nodes in one of the tree instead of iterating all the children of one tree, disconnect the current root, and connect to new root?
In that scenario you will need to disconnect the relationships from one of the root nodes to be able to attach it to the other one
Assuming there is some unique property like "name" to identify the root nodes and only 1 hop (relation) between your root nodes and leaf nodes, this query should do the work.
match (rt2 {name:"root2"})--> (n), (rt1 {name:"root1"})
detach delete rt2
create (rt1)-[:RELATED_TO]->(n)
You can use apoc.refactor.mergeNodes to "merge" the nodes in a node-list into the first node in the list, which includes essentially "moving" all the relationships over to the first node. You should read about the powerful options that are available, to get the results you want.
Here is a very simple example. This query will merge root2 into root1 (overwriting all properties in root1 having the same name as a property in root2), and essentially "move" all root2 properties over to root1:
MATCH (root1), (root2)
WHERE root1.id = 123 AND root2.id = 234
CALL apoc.refactor.mergeNodes([root1, root2], {}) YIELD node
RETURN node
You can specify options in the {} map to modify the above default behavior.

Cypher: extract only nodes with independent connections to two other nodes?

I have the following query:
MATCH (rebecca:Person)-[r1*1..3]-(robert:Person)
WHERE rebecca.name=Rebecca AND robert.name='Robert'
RETURN rebecca, robert,
extract(x IN r1 | {rel: x, start: startNode(x), end: endNode(x)})
This returns all the nodes and edges within 3 hops of both Rebecca or Robert. So it includes some nodes that are 2 hops from Rebecca, and 3 hops from Robert, where his connection is via Rebecca.
Is there a way I can exclude the nodes for which Robert's only connection is via Rebecca, and vice versa?
I'm interested in connections that they truly share independently, not where the only connection is via each other.
With 3 hops, the only possible way to go through the other is if (from Rebecca for this example):
rebecca->robert->node->robert
So robert would have to appear twice (or rebecca, from the other direction).
It seems to me that you just need a restriction that rebecca and robert must appear only once each in the path:
MATCH p=(rebecca:Person)-[r1*1..3]-(robert:Person)
WHERE rebecca.name=Rebecca AND robert.name='Robert'
AND SINGLE(rebecca in nodes(p)) AND SINGLE(robert in nodes(p))
RETURN rebecca, robert,
extract(x IN r1 | {rel: x, start: startNode(x), end: endNode(x)})

how to unwind multiple collections

my query returns rows of the form:
node | {node1, node2, node3} | {float1, float2, float3}
i would like to unwind the two collections which always have the same number of elements, so that i will get rows of the form:
node | node1 | float1
node | node2 | float2
node | node3 | float3
i tried to unwind both collections but that will return all permutations of the elements, so in this case 9 rows.
is there a simple way to achieve this using cypher?
Here is an example. It gets a collection of Nodes and a collection of Floats. Then it iterates though the size of the collection and dumps them out in tabular form. No attention to sorting ans an assumption that they are the same size collection.
MATCH (m:Top)-->(n:Float)
WITH m, collect(n.name) AS float
MATCH (m)-->(n:Node)
WITH m, float, collect(n.name) AS node, range(0,size(float)-1,1) AS coll_size
WHERE size(float) = size(node)
UNWIND coll_size AS idx
RETURN m.name, float[idx], node[idx]
Here is a sample of the output.

Neo4j - Search list with mutual count

I have created some nodes and relations in neo4j and want to query with cypher. I am explaining more about it as below.
UserID UserName
------ --------
1 UserA
2 UserB
3 UserC
4 UserD
5 UserE
6 UserF
and relationship between nodes are as follows :
UserID FriendID ApprovalStatus (1.Request Accepted, 2.Request Pending)
------ -------- ------------------------------------------------------
1 2 1
1 3 2
1 6 2
2 3 1
2 4 1
2 5 2
3 6 1
3 5 2
My Login User is node 1 (eg. UserA), and trying to search from node. and I am expecting this result from neo4j.
Record # UserID UserName MutualCount ApprovalStatus
-------- ------ -------- --------------- --------------
1 2 UserB 1 (eg. node 3) 1
2 3 Userc 0 2
3 4 UserD 0 null
4 5 UserE 0 null
5 6 UserF 0 2
check the following points :
Record # 1 :
Node3 (UserC) is mutual between Node1 & Node2 with because it has ApprovalStatus=1 with both nodes.
Record # 2 :
There is no mutual between node1 & node3, and ApprovalStatus = 2 because Node1 has sent request to node3, but it is pending yet.
Record # 3 :
Same situation as mentioned in Record # 2
Record # 4 & 5:
here is no mutual between node1 & node4, and ApprovalStatus = null because Node1 has never sent request to node4 & node5.
I have created some dummy data on here
So, you can test query. I am trying to get this result from last 10-15 days, but I can not get success. Is there any way to achieve this result.
Thanks.
The relationship table in your question doesn't have any mutual relationships, which is what it looks like you are looking for, so I created a very similar example that adds an additional relationship from B to A.
I added statuses "accepted" and "requested" to the :FRIEND relationships, but as #Stefan mentions in the comments, it would be easier to use different relationship types such as :REQUESTED_FRIEND and :FRIEND to distinguish between the two. In that case you could drop the WHERE clause from the following query:
START n=node(*)
MATCH n-[r:FRIEND]->m, m-[r2:FRIEND]->n
WHERE r.status='accepted' AND r2.status='accepted'
RETURN n, COUNT(m) AS MutualCount, COLLECT(m.name)
which returns:
n MutualCount MutualWith
(5 {name:"B"}) 1 [A]
(6 {name:"A"}) 1 [B]

Resources