Get all edges between a set of nodes with Cypher or Gremlin

2,002 views
Skip to first unread message

Nam Chu Hoai

unread,
Mar 1, 2013, 4:32:05 PM3/1/13
to ne...@googlegroups.com
Hey guys,

I'm trying to make a visualization of subgraphs in D3.js and for that, given a set of nodes, I'd like to return all edges between them to create a fancy force-directed graph. However, this tasks gets harder than I expected. I first thought it'd be pretty straightforward, but then I realized that this doesn't really fit nicely in the current Cypher Syntax, as there is no way to tell Cypher "given a node A of set N, find me all edges that connect to N\{A}"

I also tried to just mach edges and then check whether source/target are a member of set N, but that didn't work either ...

I'd appreciate any help with this simple-sounding query

Nam

Peter Neubauer

unread,
Mar 1, 2013, 4:39:30 PM3/1/13
to Neo4j User

Nam,
Have you looked into the graph algos syntax? There are a few shortest path ones, documented in the match section of the manual.

/peter

Sent from mobile device.

--
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/groups/opt_out.
 
 

Nam Chu Hoai

unread,
Mar 1, 2013, 4:55:15 PM3/1/13
to ne...@googlegroups.com
Peter, 

I actually have never noted this section of the manual, thanks for hinting me to it. After taking a look though, it seems like the algos not fitting the exact use case? Like the tricky part seems to be the qualification that I only want edges that connect to nodes inside the set.

WIth Cypher, it'd currently works like this:
start set=node(1,2,3), root=node(1) match set-[edge]-nodes where nodes--root return set, edge, nodes

However, the last qualification makes cypher check every node, so its probably O(count(nodes)), and therefore not accetable.

Does that make sense?

Nam

--
You received this message because you are subscribed to a topic in the Google Groups "Neo4j" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/neo4j/hl2ssBKsvnc/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to neo4j+un...@googlegroups.com.

Marko Rodriguez

unread,
Mar 1, 2013, 4:57:57 PM3/1/13
to ne...@googlegroups.com
Hi,

If you just want all edges (meaning, 1-degree), do this in Gremlin:

g.v(1).outE.inV.retain([g.v(2)]).back(2)

If you are talking arbitrary depth, do:

g.v(1).outE.inV.loop(2){it.object != g.v(2)}.retain([g.v(2)]).path

In the returned path array you will see vertex -> edge -> vertex -> edge *

The last traversal is scary cause you could have infinite loops and reverberating paths. You could do this:

g.v(1).outE.inV.loop(2){isSimple(it.path) & it.object != g.v(2) & it.loops < 4}.retain([g.v(2)]).path

Where 4 is just some arbitrary depth to give up at and isSimple() can be defined as "new HashSet(it.path).size() == it.path.size()."

Note that this is directional and bi-directional search. The GraphAlgos package in Neo4j uses bidirectional search. There is an implementation in Furnace (http://furnace.tinkerpop.com), but it hasn't be release yet.

Good luck,
Marko.

Nam Chu Hoai

unread,
Mar 1, 2013, 5:04:36 PM3/1/13
to ne...@googlegroups.com
Marko,

im not familiar with gremlin, but I assume I'm looking for the first query? If I understood correctly, 

g.v(set).outE.inV 
are the connections of the set

.retain(g.v(set)) 
restricts these then only to the nodes that are within the set?

Question: If that is indeed the case, how do I then get the edges returned, since the cursor/focus seems to be on the set agian and not the edges?

Nam

--
You received this message because you are subscribed to a topic in the Google Groups "Neo4j" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/neo4j/hl2ssBKsvnc/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to neo4j+un...@googlegroups.com.

Marko Rodriguez

unread,
Mar 1, 2013, 5:11:40 PM3/1/13
to ne...@googlegroups.com
Hi,


im not familiar with gremlin, but I assume I'm looking for the first query? If I understood correctly, 

g.v(set).outE.inV 
are the connections of the set

Yes. That will give you all vertices outgoing adjacent to the vertices in g.v(set).

.retain(g.v(set)) 
restricts these then only to the nodes that are within the set?

Yes. Now you are only at the vertices in that set (again).

Question: If that is indeed the case, how do I then get the edges returned, since the cursor/focus seems to be on the set agian and not the edges?

back(2) to go back to steps to the edge.

You could also do this:

g.v(set).outE.as('x').inV.retain(set).select('x')

  -OR-

g.v(set).outE.as('x').inV.retain(set).back('x')

select() is more powerful as you can arbitrarily project elements from anywhere in your pipeline. However, since you only want one object, you are only projecting one thing…the thing that is 2 steps previous (named 'x').

Marko.

Michael Hunger

unread,
Mar 2, 2013, 11:17:47 AM3/2/13
to ne...@googlegroups.com
Start n=nodes({set}), m=nodes({set})
Match n-[r]-m
Return r

Sent from mobile device
--
Reply all
Reply to author
Forward
0 new messages