Export procedure that returns serialized RDF

I was playing around with invoking the rdf cypher export in n10s and realized that you can't get the result back as RDF, you have to convert the returned triple rows into an RDF model yourself, unless you use the HTTP endpoint.

Is it possible to have an N10S procedure that takes an RDF format as a parameter and will return the RDF is a single result entry? I would just use the n10s endpoint, but I'm having a really strange issue with the response from my jax-rs client in my java code. The issue is not related to n10s, it's something bizarre with a project dependency conflicting with something else and I haven't found the cause yet. I was hoping avoiding the http calls would be a way to avoid this issue. For now I think I'll need to switch back to http and see if I can solve the other issue.

I still think it would be useful if the conversion to an RDF format could be done for you in the cypher procedure, or an equivalent easy way to do it.

Thanks!
Ryan

Hi @r_moquin ,
Thanks for sharing your experience. This is exactly the type of feedback we need :slight_smile:
Let me explain our thinking: while the RDF endpoint is a convenient component to generate RDF out of data in Neo4j, it's not a great architectural approach to have an HTTP API tightly coupled with the DB. That's essentially the rationale behind the n10s.rdf.export procedures (both spo and cypher). Serialising the triples as records over a neo4j/bolt connection (instead of HTTP) makes it possible for a client application to query neo4j via cypher using the official drivers and therefore being able to work with a cluster, wit aura (neo4j DBaaS) , or in any deployment where direct HTTP to the DB is not an option. The client calls the n10s.rdf.export procedures to get the triples serialised as records and then can reconstitute them for serialisation or process them with a client RDF library (pretty trivial step).

This is exactly what the rdflib-neo4j does if you use python + rdflib.
The idea is to extend this concept to other RDF libraries in other languages (java + rdflib or jena), etc.

I'll share soon a simple example (a handful of lines of python) of how to create an RDF HTTP endpoint detached from the DB following this approach. Watch this space.

What I've described effectively delegates the final serialisation to the client but I hear your suggestion of adding a method that would do it on the server side and return a blob of RDF (basically a long string) instead of a collection of individual triples as records.

Did I interpret your question correctly?

I'm open to this but would like to understand a bit more about your approach. Could you share how the client would use the returned RDF?

Cheers,

JB.

Thanks for sharing the roadmap for that @jesus_barrasa
I would also appreciate having an officially supported by Neo4j way to export serialized string.
The workflow for my use case would be as follows:

  • starting from data in Neo4j format (nodes and relationships without uri), assign a uri based on values of selected properties of nodes e.g.(:Car{model:'toyota'}) gets a new property::Car{model:'toyota', uri:'neo4j://graph.schema#Car#toyota'}) In the future might need support of generating uri as well based on data from neighboring nodes

  • save a subgraph (based on cypher query) as RDF
    like with :POST /rdf/neo4j/cypher {"cypher": "MATCH (c:Car) RETURN c", "format": "Turtle"} but via bolt

  • Neo4j might get updated in the meantime (e.g. MATCH (c:Car{model:'toyota'}) DELETE c)

  • restore the saved subgraph (the entities get MERGEd by uri created in the first step) call n10s.rdf.import.fetch(url, "Turtle")

Hi JB, yes you interpreted correctly. To be completely honest, I wasn't sure how much work it would be to translate the returned triples to RDF, if it's trivial, then I'll just write the code to do it :) I'll take a look at the rdflib-neo4j library, I didn't realize that existed.

We actually wrote a rest service in front of our Neo4j server because we agree that direct access by clients to the Neosemantics endpoint isn't great architecturally either. This also allows us freedom to manipulate the JSON-LD we return and frame it how we want as well. I think that would be preferable to cluttering up Neosemantics with a ton of configuration and options. The only use case I had for this request was simply so I could switch to use a bolt connection rather than HTTP. I wasn't sure how much effort it might be to convert the records into RDF that we could process further with RDF4j (such as what various conditions to check for in the records to make sure we end up with a correct rehydration of the triples).

I'll take a look at writing the Java code to do the conversion and reference your example.

Thanks Jesus!
Ryan

1 Like