aplbrain / grand-cypher Goto Github PK
View Code? Open in Web Editor NEWImplementation of the Cypher language for searching NetworkX graphs
License: Apache License 2.0
Implementation of the Cypher language for searching NetworkX graphs
License: Apache License 2.0
since NetworkXDialect is inherited from networkx.Graph, there happens to be discrepancies between networkx.Graph and networkx.Digraph popagated back to grand.Graph. One of them is the networkx.Graph.edges return EdgeView while networkx.Digraph.edges return OutEdgeView.
Below is one of the test to replicate the issue
def test_nx_edges(self):
G = Graph(directed=True).nx
H = nx.DiGraph()
G.add_edge("1", "2")
G.add_edge("2", "1") # <<< this won't work with EdgeView for G
G.add_edge("1", "3")
H.add_edge("1", "2")
H.add_edge("2", "1") # <<< OutEdgeView returns this for H
H.add_edge("1", "3")
self.assertEqual(dict(G.edges), dict(H.edges))
self.assertEqual(dict(G.edges()), dict(H.edges()))
self.assertEqual(list(G.edges["1", "2"]), list(H.edges["1", "2"]))
the result is
def test_nx_edges(self):
G = Graph(directed=True).nx
H = nx.DiGraph()
# H = nx.Graph()
G.add_edge("1", "2")
G.add_edge("2", "1")
G.add_edge("1", "3")
H.add_edge("1", "2")
H.add_edge("2", "1")
H.add_edge("1", "3")
> self.assertEqual(dict(G.edges), dict(H.edges))
E AssertionError: {('1', '2'): {}, ('1', '3'): {}} != {('1', '2'): {}, ('1', '3'): {}, ('2', '1'): {}}
E - {('1', '2'): {}, ('1', '3'): {}}
E + {('1', '2'): {}, ('1', '3'): {}, ('2', '1'): {}}
E ? ++++++++++++++++
In building multi-hop queries, is there currently a method to retrieve the node ids along with the attributes?
i.e for the query
MATCH (A{id: "Vikings"})-[R*0..3]->(B{id: "England"})
RETURN A, R, B
LIMIT 1
The source and target nodes could be added as attributes. In looking at the code, it's also straightforward to add those in all cases or with multi-hop relationships. Lastly, the openCypher standard has startNode
and endNode
functions.
Curious if there are any thoughts on this use case.
My use case is a perfect fit for this feature. I do not know exactly the depth of a branch, so I would like to search for depth starting from a node all the way down or to a limit. It would be good if edge hopping or variable relationship is supported.
From what I understand, the syntax for it is -[*min..max]-
where min and max are positive integers. The result is subgraphs having that branch node reaching out from min to max.
This will improve the performance of queries with LIMIT arguments.
Awesome library! Exactly what i needed. Aggregate functions don't seem to work though
https://neo4j.com/docs/cypher-manual/current/functions/aggregating/
For example, the syntax:
MATCH p=(n1 {type: "compilation_unit"})-[]->(n2 {type: "class_declaration"})-[*2]->(n3 {type: "method_declaration"})-->(n4 {text: "Main", type:"identifier"})
RETURN p
The return type for a path from neo4j has start, end, segments
, and notably includes nodes or edge that would be traversed by the edge *
operator.
I can still work around it, but I would very much like to have access to variable-length paths!
Graph mutations (updating, deleting, and creating vertices using Cypher) are a big engineering change, and will likely require a lot of corner-case tests.
I previously listed this as a "not-planned" feature but I wonder if users are interested in this capability existing? Perhaps @khoale88, I wonder what your current use-cases look like? I would be interested in adding this feature back into the roadmap if it will be useful!
This involves AND/OR/NOT support (with order-of-operations to match that of Cypher) with parentheses. I think this might be pretty complicated because it will entail backtracking the entire structural match if clauses aren't met; it might make more sense to run OR
operands in parallel, so that
MATCH (A)
WHERE (A.type = 1 AND B.type = 1) OR (B.type = 2)
RETURN A
becomes two queries:
MATCH (A)
WHERE (A.type = 1 AND B.type = 1)
RETURN A
MATCH (A)
WHERE (B.type = 2)
RETURN A
But I imagine this will get much more complicated for deeper nesting.
I believe the license is Apache 2.0 but it comes up as MIT on PyPI due to this line: https://github.com/aplbrain/grand-cypher/blob/master/setup.py#L18?
In Cypher, node and edge types are represented by :ColonNotation
. For example,
(A:Neuron)-[AB:Synapse]->(B:Neuron)
NetworkX has no concept of entity "types," so this will be the first time that this codebase mandates a data schema (i.e., a type
attribute on the entities in the graph). I'm not sure this is something I want to enforce, but if we do decide to use vertex/edge attributes like this, I'd like to open discussion in this issue to establish what schema we want to support.
@j6k4m8 do you have any idea how the implementation for optional match should be? Not sure if isomorphic search can do this. This is helpful for query with variable/dynamic length of relationship
Hello, thank you for the great project :)
In how far are equijoins exactly supported?
Given that I have the following NetworkX graph:
G = nx.DiGraph()
G.add_node("x")
G.add_node("y")
G.add_node("z")
G.add_edge("x", "y")
G.add_edge("y", "x")
G.add_edge("x", "x")
G.add_edge("z", "x")
When I execute the following query:
MATCH (n)-->(n)
RETURN n
I get the result:
{Token('CNAME', 'n'): ['x', 'y']}
However, if I execute the same query on the equivalent graph in neo4j, I only get the node x as result - which to my understanding of Cypher would be the correct result.
Therefore, to my understanding, equijoins are currently only supported in the project when they are distributed over multiple match
clauses and do not recognizes self cycles on nodes. Is that correct?
For instances, the following query correctly recognizes two loops in the graph:
MATCH (n)-->(m)
MATCH (m)-->(n)
RETURN n, m
While neo4j additionally returns n=x and m=x as a result.
Many regards,
Felix
I apologize for asking this from a place of relatively little understanding. I am working with a project which has brought me further into graphs than I have ever ventured before. For my project I need a way to query my graph for nodes which match a pattern. For the moment I am using https://geronimo-iia.github.io/networkx-query/ . However, I am curious to use this library for the expansive capabilities of cypher
. Is it possible to make this query work within the supported syntax of the library?
MATCH (c:City)
WHERE c.name = "London"
RETURN c
I'm reading through the source code to try to answer this for myself but there are a lot of new concepts being introduced to me all at once so I figured it wouldn't hurt to ask. I appreciate the time and effort!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.