K-hop Query Using Cypher

94 views
Skip to first unread message

Kamilos

unread,
Apr 13, 2016, 2:52:03 AM4/13/16
to Neo4j
hello,
I'm trying to compute the k-hop using cypher.

The idea is the following :
 The nodes at distance 1 from start node should be marked "NodesDist1",
 then, nodes at distance 2 should be names "NodesDist2" but they should not be the same as "NodeDistance1".
 Again, the nodes at Distance 3, should be different than the in NodesDist1 and NodesDistance2. See Image for more clarifications.

























Just getting the nodes from the outgoing edges is not a good solution because the nodes from the outgoing edges may already been seen in, for instance, NodesDist1.

So I need I a way to filter them.


This is what i got from the moment. However the "where filter" is not working, apparatently i cannot do that ? 


MATCH (a:Person{name:1})-->b-->c  
with collect(DISTINCT(b.name)) as nodesDist1, collect(DISTINCT(c.name)) as nodesDist2, 
where filter(x IN nodesDist2 WHERE not(x in nodesDist1)) as res return res"); 


So I'm looking for a way to do this query in cypher.

Michael Hunger

unread,
Apr 13, 2016, 3:39:53 AM4/13/16
to ne...@googlegroups.com
Try this:

MATCH (a:Person{name:1})-->(b)-->(c)-->(d)
with collect(DISTINCT b) as nodesDist1, collect(DISTINCT c) as nodesDist2,collect(DISTINCT d) as nodesDist3
RETURN nodesDist1,
                filter(n in nodesDist2 WHERE NOT n in nodesDist1) as nodesDist2, 
                filter(n in nodesDist3 WHERE NOT n in nodesDist1 OR n in nodesDist2) as nodesDist3


--
You received this message because you are subscribed to the Google Groups "Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to neo4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kamilos

unread,
Apr 13, 2016, 12:21:36 PM4/13/16
to Neo4j


Le mercredi 13 avril 2016 09:39:53 UTC+2, Michael Hunger a écrit :
Try this:

MATCH (a:Person{name:1})-->(b)-->(c)-->(d)
with collect(DISTINCT b) as nodesDist1, collect(DISTINCT c) as nodesDist2,collect(DISTINCT d) as nodesDist3
RETURN nodesDist1,
                filter(n in nodesDist2 WHERE NOT n in nodesDist1) as nodesDist2, 
                filter(n in nodesDist3 WHERE NOT n in nodesDist1 OR n in nodesDist2) as nodesDist3


Indeed,it's working well, I just had to replace the  "OR"  by "AND NOT"


However, isn"t there a way to optimise this query ?

Because, I have the impression that we are, for instance, collecting all the D nodes from all the C nodes and then doing a filtering on them.

Wouldn"t it be better if we first filtered the C nodes to the relevant ones and then, starting from this reduced subset, looked for the D nodes ?

Michael Hunger

unread,
Apr 13, 2016, 9:21:56 PM4/13/16
to ne...@googlegroups.com
yes sure :)

MATCH (a:Person{name:1})-->(b)-->(c)
with collect(DISTINCT b) as nodesDist1, c
MATCH (c)-->(d)
with nodesDist1, filter(n in collect(DISTINCT c) WHERE NOT n in nodesDist1) as nodesDist2,collect(DISTINCT d) as nodesDist3
RETURN nodesDist1,nodeDist2,
                filter(n in nodesDist3 WHERE NOT (n in nodesDist1 OR n in nodesDist2)) as nodesDist3

--

Kamilos

unread,
Apr 15, 2016, 9:46:14 AM4/15/16
to Neo4j
okay perfect thanks :)
Reply all
Reply to author
Forward
0 new messages