How to find shortest path between nodes on a directed graph in neo4j? - graph

Using graph algorithms extension and the inbuilt shortest-path search in neo4j does not look at the direction of the relationships as long as 2 nodes are connected. Is there a way to query the graph db to include the directionality of the relationships connecting nodes, or would you have to code dijikstra's from scratch without leveraging neo4j and its graph algorithm library capabilities?
I'm currently using a query structured in this fashion:
MATCH (start:Db_Nodes{uid:"xxx"}),(end:Db_Nodes{uid:"yyy"}) CALL algo.shortestPath.stream(start, end, "weight") YIELD nodeId, cost MATCH (node) WHERE id(node) = nodeId RETURN node

The APOC procedure apoc.algo.dijkstra should work for you.
For instance, if you want the shortest weighted path with only outgoing relationships from start to end (regardless of relationship type):
MATCH (start:Db_Nodes{uid:"xxx"}), (end:Db_Nodes{uid:"yyy"})
CALL apoc.algo.dijkstra(start, end, '>', 'weight') YIELD path, weight AS totalWeight
RETURN path, totalWeight;

Related

Generalized subqueries in Cypher 9

I have a graph in Neo4j, where all nodes and edges have a property p. With a cypher query as follows, I get a subgraph of the whole graph that fulfills several conditions on p for vertices and edges in general.
Q1
MATCH (n)
WHERE n.p ... // some conditions for nodes
OPTIONAL MATCH (n)-[r]-()
WHERE r.p ... // some conditions for relationships
RETURN n,r
Now I want to execute a second query Q2 on the resulting subgraph of the first query Q1. For example
Q2
MATCH (a:Person)-[:knows*5]-(b:Person)-[s:studiedAt]-(u:University),
(b)-[:owns]-(i:Business)
WHERE i.city = "Boston"
RETURN DISTINCT a.name, i.name, u.name
I do not want to apply the general conditions of Q1 for each vertex and edge in Q2. That complicates the query, loses the generalization, and needs path variables for variable paths like [:knows*5].
Is there a smarter way to execute a query Q2 on the result of a query Q1? Or is this impossible in Cypher because of its missing composability and the fact, that the result is always a table and never a graph?
It's not present directly in Cypher as far as I know, but if you are using Neo4j Enterprise, then you can use Neo4j Graph Data Science Library, to create named subgraphs, and then you can query those subgraphs. The disadvantage that comes with this approach is your subgraph won't be updated as the original graph gets updated. Please go through the following documentation, on how to create a subgraph:
Projecting a subgraph
Querying your subgraph

Gremlin OLAP traversal query error regarding local star-graph

I'm trying to execute an OLAP traversal on a query that needs to check if a vertex has a neighbour of certain type.
i keep getting
Local traversals may not traverse past the local star-graph on GraphComputer
my query looks something like:
g.V().hasLabel('label1').
where(_.out().hasLable('label2'))
I'm using the TraversalVertexProgram.
needless to say, when running the same query in oltp mode there is no problem
is there a way to execute such logic?
That is limitation of TinkerPop OLAP GraphComputer. It operate on 'star-graph' objects. The vertex and connected edges only. It uses message passing engine inside. So you have to rewrite you query.
Option 1: start from label2 and go t label1. This should return the same result
g.V().hasLabel('label2').in().hasLabel('label1')
Option2: try to use unique edge labels and check edge label instead
g.V().hasLabel('label1').where(_.outE('label1_label2'))

How to get the list of all incoming intermediate vertices between a source vertex and target vertex of specific label using Gremlin query?

The Gremlin query that I use to get the list of all outgoing vertices (with edge label “has”) from a selected vertex “P1” until it reaches the vertex with specific label “L3” is this:
g.V().has("id”,”P1”).repeat(out(“has”)).until(hasLabel(“L3”)).path().by("id")
As expected, the query above returns me the list of all intermediate nodes between selected vertex and target vertex labeled “L3”.
However, when using the same query (changing the ‘out’ to ‘in’) in opposite direction, i.e., to get the list of all incoming vertices from a selected vertex to the target vertex with specific label, i get a gremlin query error straight away.
Here is the query:
g.V().has("id”,”P3”).repeat(in(“has”)).until(hasLabel(“L1”)).path().by("id")
The error looks like this:
Failure in submitting query:
Error: Script compile error: Missing ')'
I don’t see any missing brackets in the query though and the only change between the queries for incoming or outgoing vertices i made is using ‘in’ instead of ‘out’.
In the official tinkerpop documentation (https://tinkerpop.apache.org/docs/3.2.9/reference/#_traversal_strategies_2), in traversal strategies, I cannot find any example with repeat(in()), only with repeat(out()). Is there a special query or method to get all the incoming vertices from a selected vertex until it reaches the vertex with a specific label?
I'm not sure if this is your problem or not, but I could see where you would get an error because "in" is a reserved word in Groovy so, you have to explicitly spawn it using the anonymous traversal class with: __.in(), therefore:
g.V().has("id","P3").repeat(__.in("has")).until(hasLabel("L1")).path().by("id")
This issue is documented in a number of places in the Reference Documentation, but perhaps you missed it (you referenced a fairly old version of the documentation as well) - described here in a NOTE in the Vertex Steps for example.

Cypher query that aggregate edges of neo4j multigraph and return a simple graph

We have a multi-graph of email connections. In this graph there are many edges between 2 nodes. Is there any cypher query to aggregate all edges between each node pairs and then return a new graph?
ATTENTION: I know the query that aggregate edges, but it returns a table, not graph!
To visualize the relationships together you can use apoc's virtual relationships:
MATCH (a:Foo)-[r]->(b:Bar)
RETURN a,b, apoc.create.vRelationship(a,'COMBINED',{count:count(*)},b) as rel

Querying titan graph for only indexed vertices without traversing complete graph

I am trying to retrieve only indexed vertices in the graph
I used the below query
Iterator<Vertex> vertices = titanTransaction.query().has("name").vertices().iterator();
This query traverses to the complete graph and fetches the result, Can anyone suggest me a better way, The name vertex is indexed.
Thanks
You should be able to use the .has(key,value) method https://github.com/thinkaurelius/titan/blob/0.5.4/titan-core/src/main/java/com/thinkaurelius/titan/graphdb/query/graph/GraphCentricQueryBuilder.java#L113
Iterator<Vertex> vertices = titanTransaction.query().has("name","john").vertices().iterator();
Should do the trick.
Have you tried:
graph.V('name','nameOfTargetVertex').next()
I think this should use your index on the attribute name, according to http://gremlindocs.com/#transform/v .

Resources