scholrly / neo4django

Drop-in Neo4j/Django integration.
GNU General Public License v3.0
358 stars 83 forks source link

Querying/Graph traversal #123

Open benjiec opened 12 years ago

benjiec commented 12 years ago

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 commented 12 years ago

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 commented 12 years ago

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

ambsw-technology commented 7 years ago

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.