I am using DSE-5.0.5 and DSE-studio and want to write a query in gremlin inside notebook graph.
Is there a intersect query that could give me common elements between two sets returned via traversal in tinkerpop3 .
I have written this query:
g.V().has('name','Person1').outE('BELONGS').inV().inE('HAS').outV().as('x').inE('HAS').outV().as('y').inE('HAS').outV().has('name','App1').select('x').inE('HAS').outV().hasLabel('Org').as('p').repeat(out()).until(outE().hasLabel('IS')).as('a1').select('y').inE('HAS').outV().hasLabel('Class').repeat(inE('IS').dedup().otherV()).until(inE().hasLabel('HAS')).as('a2').select('a1','a2')
So I want an intersection of sets a1 and a2.
Or is there an efficient way of writing this which could give me that?
It would have been helpful to have a sample graph, but I think this should work:
g.V().has("name","Person1").
out("BELONGS").in("HAS").dedup().as("x").
in("HAS").filter(__.in("HAS").has("name","App1")).store("y").
select("x").dedup().in("HAS").hasLabel("Org").
repeat(out()).until(outE().hasLabel("IS")).store("a").cap("y").
unfold().in("HAS").hasLabel("Class").
repeat(inE("IS").dedup().otherV()).until(inE("HAS")).
where(within("a"))
Related
I would like to show on the graph all connections (max.6) from the specific node (Company).
I simply used the below:
MATCH path=(c:Company)-[*1..6]-()
where c.property1=$company
RETURN path, c
but it takes lot of time to execute the query.
Any suggestion how to modify this query or how to speed up the process?
Best regards!
First of all, traversing 6 hops can be a lot especially in a well-connected graph.
However, I would suggest you use the following query to optimize your search:
MATCH path=shortestPath((c:Company)-[*1..6]-(e))
where c.property1=$company AND NOT c = e
RETURN path, c
I'm trying to understand Neo4j's mechanics when dealing with path searches. I studied the query patterns and execution plan operators in the developer manual, but I still have some questions.
Please correct me if I'm wrong, but from the content I read, and from some posts on Neo4j's blog, I understood that Cypher and Java traversals generally perform depth-first searches, more specifically informed searches, and that variable-length queries fit into it. I also read that shortest path planning uses a breadth-first bidirectional search, and a depth-first search as a fallback.
Is there any way to perform breadth-first searches in Neo4j other than that?
I know the APOC procedures library allows this kind of search through path expanders, but I'm limiting my scope to just the Cypher language for now.
Also, does the variable-length pattern run recursively?
And what kinds of filtering are executed during expansion? I read that functions like ALL normally are checked during expansion, but some are executed later.
The reason for these questions is to see to what extent I would be able to manipulate the data and make complex traversals using only Cypher and what already comes with Neo4j, without external libraries and without having to write procedures through the API.
Forgive me if these questions are trivial. Thanks in advance.
Being a declarative query language Cypher doesnot controls how the underlying engine will search the pattern. So by just specifying a pattern we cannot specify which pattern matching algorithm shall be used for finding patterns. So we cannot perform breath first algorithm with just using Cypher.
For running a variable length pattern recursively we can use kleene star over single edge labels for example :KNOWS* or we can use the or operator in cypher for example :KNOWS|FOLLOWS* in cypher. Essentially this means (KNOWS|FOLLOWS)* in Regular Path Query (RPQ) format. Which is equivalent to (a|b)* in regular expression syntax. We can also have more edge labels such as (a|b|c|....)* in cypher.
We can also specify a varibale length over the pattern as ()-[:KNOWS|FOLLOWS*1..6]->() in cypher.
However we cannot do recursive iterations over a few pattern for example a sub-graph which has a node with one incoming edge and atleast two out going edges from the same node. for example a pattern such as this (a)-[r]->(b)-[s]->(c), (b)-[v]->(d). This is an example of a conjunctive pattern.
Filtering can be is normally performed in the WHERE clause based on the property key value pairs. We can set the labels in the pattern expressed in the MATCH clause so that the underlying engine knows the start node. For example as done in the following query
match (a:Person{name:'Keanu Reeves'})-[r]->(b) return * limit 5
I am confused as what is the difference between below two ways to create a node ? It seems like the result is the same;
from py2neo import Graph
graph = Graph()
graph.cypher.execute("CREATE (a:Person {name:{N}})", {"N": "Alice"}) # a
graph.create( Node("Person",name="Alice")) # b
Looking at the py2neo v3 documentation, it seems there's yet a third way to create a node.
First instantiate a Node object, as in
a = Node("Person",name="Alice")
then insert it in a subgraph (see py2neo types),
sg = Subgraph(a)
then create elements of this subgraph (Graph.create method):
graph.create(sg)
I understand that subgraph creation should however be preferred when creating numerous nodes and edges (a subgraph ...).
You're right, the result is exactly the same. Py2neo exposes two levels of API: a pure Cypher API (execute) and a simpler object-based API (Node). The latter is generally easier to get up and running with, the former is more comprehensive.
I've got my graph database, populated with nodes, relationships, properties etc. I'd like to see an overview of how the whole database is connected, each relationship to each node, properties of a node etc.
I don't mean view each individual node, but rather something like an ERD from a relational database, something like this, with the node labels. Is this possible?
You can use the metadata by running the command call db.schema().
In Neo4j v4 call db.schema() is deprecated, you can now use call db.schema.visualization()
As far as I know, there is no straight-forward way to get a nicely pictured diagram of a neo4j database structure.
There is a pre-defined query in the neo4j browser which finds all node types and their relationships. However, it traverses the complete graph and may fail due to memory errors if you have to much data.
Also, there is neoprofiler. It's a tool which claims to so what you ask. I never tried and it didn't get too many updates lately. Still worth a try: https://github.com/moxious/neoprofiler
Even though this is not a graphical representation, this query will give you an idea on what type of nodes are connected to other nodes with what type of relationship.
MATCH (n)
OPTIONAL MATCH (n)-[r]->(x)
WITH DISTINCT {l1: labels(n), r: type(r), l2: labels(x)}
AS `first degree connection`
RETURN `first degree connection`;
You could use this query to then unwind the labels to write that next cypher query dynamically (via a scripting language and using the REST API) and then paste that query back into the neo4j browser to get an example set of the data.
But this should be good enough to get an overview of your graph. Expand from here.
I want to find the spanning tree from graph with loops. I cannot use regular bfs traversal here. so I check the allsimplepaths java function api, It seems find loop between two nodes. right now i select a random root, but don't know the end points. so i just want to get the spanning tree from graph while the it has many loops maybe. so it should convert to DAG and then give the tree structures. The graph may have more than one spanning tree.
how to do this? can allsimplepaths applied here?
Look at TraversalDescription with an appropriate uniqueness (NODE_GLOBAL) and Path-Expanders that follow the interesting relationships.