Cypher query that aggregate edges of neo4j multigraph and return a simple graph - 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

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

How can I sort nodes by in degree with gremlin?

I need to sort nodes by their out-degree.
In neo4j with cypher query language, I do do something like:
MATCH (P1:P)
RETURN P1,size((P1)-->()) as degree
ORDER BY degree DESC LIMIT 10
In gremlin, I know how to count the out degree for each node:
g.V().hasLabel('V')
.order().by(out('E').count(), desc)
.limit(10)
However, I don't see how to return the count as well as the node itself.
Is there any way to make query like this in gremlin?
You can project the degree:
g.V().hasLabel('V').
project('vertex', 'degree')
.by(identity())
.by(out('E').count())
.order().by(select('degree'), desc)
.limit(10)
example: https://gremlify.com/c3bw9gpr36o5k

Tinkerpop Gremlin: Batching of multiple select query into one batch select query

In Tinkerpop Gremlin,
I have two select query
g.V().has("id","foo").out().values("x").toList();
g.V().has("bar","foo").out().values("id").toList();
Now Can we club these query into one batched tinkerpop gremlin?
I tried
g.V().has("id","foo").out().values("x").union(__.V().has("bar","foo").out().values("id")).toList()
but this leads to a single list instead of two separate list. I want to extract the response of these two queries separately.
You could start your traversal with some dummy value and then union() the two traversals together:
gremlin> g.inject(0).union(V(1).out().fold(),V(2).in().fold())
==>[v[3],v[2],v[4]]
==>[v[1]]

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

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;

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