Querying/Graph traversal #123

Open
benjiec opened this Issue Jul 25, 2012 · 3 comments

Comments

Projects
None yet
3 participants
@benjiec

benjiec commented Jul 25, 2012

Hi

If I load my models into Neo4j using neo4django (which I have), what kind of traversal can I do? It seems like I can use familiar Django ORM style syntax to get nodes back, but can I issue queries in Gremlin/Cypher flavor to get downstream nodes? E.g. what if I want to see if node X can reach node Y?

Thanks.

@mhluongo

This comment has been minimized.

Show comment
Hide comment
@mhluongo

mhluongo Jul 29, 2012

Member

Right now, we only publicly support the regular ORM syntax, including many queryset operations. While these cover many basic traversal use cases (and some complicated ones, using select_related), some traversals are difficult to express (eg recursive traversals).

There are plans to add a more powerful and natural Gremlin/Cypher interface, though, and there are also internal methods you can use if you need.

Because we use Gremlin and Cypher extensively in the library, we have a process to load and persist Groovy source files server-side (neo4django.neo4jclient.load_library(library_class_name, source_file_path)), and gremlin(), gremlin_tx(), and cypher() methods on connection objects (neo4django.neo4jclient.EnhancedGraphDatabase). Unfortunately, the results from these calls can't be easily wrapped when they return to the client (since you could make aggregate calls, etc in Gremlin and not necessarily return nodes or relationships), so that's left to the developer. I've written a gist example of using Cypher and wrapping the results in Django models.

I've been playing with some ideas for how to better involve Gremlin and Cypher from a user perspective, instead of just generating it within the library. In particular, I've thought about adding a queryset method to inject Gremlin into a query- maybe something like

Model.objects.filter(name='Neo').gremlin('it.out.out')

to get all nodes that are two hops from any Model instance named "Neo" (trivial example obviously). WDYT?

Member

mhluongo commented Jul 29, 2012

Right now, we only publicly support the regular ORM syntax, including many queryset operations. While these cover many basic traversal use cases (and some complicated ones, using select_related), some traversals are difficult to express (eg recursive traversals).

There are plans to add a more powerful and natural Gremlin/Cypher interface, though, and there are also internal methods you can use if you need.

Because we use Gremlin and Cypher extensively in the library, we have a process to load and persist Groovy source files server-side (neo4django.neo4jclient.load_library(library_class_name, source_file_path)), and gremlin(), gremlin_tx(), and cypher() methods on connection objects (neo4django.neo4jclient.EnhancedGraphDatabase). Unfortunately, the results from these calls can't be easily wrapped when they return to the client (since you could make aggregate calls, etc in Gremlin and not necessarily return nodes or relationships), so that's left to the developer. I've written a gist example of using Cypher and wrapping the results in Django models.

I've been playing with some ideas for how to better involve Gremlin and Cypher from a user perspective, instead of just generating it within the library. In particular, I've thought about adding a queryset method to inject Gremlin into a query- maybe something like

Model.objects.filter(name='Neo').gremlin('it.out.out')

to get all nodes that are two hops from any Model instance named "Neo" (trivial example obviously). WDYT?

@mhluongo

This comment has been minimized.

Show comment
Hide comment
@mhluongo

mhluongo Jul 29, 2012

Member

I'm going to leave this issue open to invite discussion. Please post if you have any ideas/feedback!

Member

mhluongo commented Jul 29, 2012

I'm going to leave this issue open to invite discussion. Please post if you have any ideas/feedback!

@ambsw-technology

This comment has been minimized.

Show comment
Hide comment
@ambsw-technology

ambsw-technology Jun 23, 2017

Maybe you could start with the "raw" SQL interface:

https://docs.djangoproject.com/en/1.11/topics/db/sql/

The caller asserts the object type by calling <type>.objects.raw(...) and the existing raw syntax supports annotations (i.e. fields not present in the model). If you want to support multiple languages through the same raw interface, maybe you could add a language kwarg.

The "Executing custom SQL directly" lower on the page is also an official interface for model-free queries.

I realize it's not quite the inline syntax to which you aspire, but it would give users access to the full power of the language while you worked through a more intuitive api.

Maybe you could start with the "raw" SQL interface:

https://docs.djangoproject.com/en/1.11/topics/db/sql/

The caller asserts the object type by calling <type>.objects.raw(...) and the existing raw syntax supports annotations (i.e. fields not present in the model). If you want to support multiple languages through the same raw interface, maybe you could add a language kwarg.

The "Executing custom SQL directly" lower on the page is also an official interface for model-free queries.

I realize it's not quite the inline syntax to which you aspire, but it would give users access to the full power of the language while you worked through a more intuitive api.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment