Property Graph - RDF Experimental Converter: Translate Property Graphs into RDF graphs by bringing extra semantic by using a context
PREC is a set of tools to convert any Property Graph into RDF.
Its main differences with other converters are:
PREC uses the PREC ontology that is described at https://bruy.at/prec. The PREC
ontology is mostly used to describe how to convert an RDF graph generated by
PREC with its default modelling into a more user-friendly graph.
The repository contains a data folder with some exportation of Neo4j data by
using the APOC plugin. PREC can be quickly experimented by using these provided
example files.
git clone https://github.com/BruJu/PREC
npm install --save-dev
Example 1: A Property Graph with a node about the POTUS
npx ts-node prec.ts apoc2rdf data\ex1_potus.json -c data\ex1_prsc.ttl
data\ex1_potus.json
contains the exportation of a Neo4J Property Graphdata\ex1_prsc.ttl
is a context. In this project, we call aExample 2: The node Ann likes the node Dan
npx ts-node prec.ts apoc2rdf data\ex2_annlikesdan1.json -c data\anndan.ttl
It is possible to import PREC to get access to functions to produce RDF graphs
from a Gremlin or a Neo4j connection. The produced output will be an
RDF/JS DatasetCore.
In this example, we want to count the number of nodes and edges in
a local instance of a Neo4j property graph. Because simply looking at
Neo4j Desktop or using properly the Neo4j JS API would be too easy, we are going
to use PREC and count the nodes and edges in the PG thanks to the produced RDF
graph.
// Property Graph API
import neo4j from 'neo4j-driver';
// Some useful RDF imports
import { DataFactory } from 'n3';
import namespace from '@rdfjs/namespace';
const rdf = namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#", { factory: DataFactory });
const pgo = namespace("http://ii.uwb.edu.pl/pgo#" , { factory: DataFactory });
// PREC
import { cypherToRDF } from 'prec';
// Open the connection
const auth = neo4j.auth.basic('neo4j', 'password');
const driver = neo4j.driver('neo4j://localhost:7687/neo4j', auth);
// Build an RDF graph
cypherToRDF(driver)
.then(graph => {
// We can now count
console.log(graph.match(undefined, rdf.type, pgo.Node).size + " nodes in the PG");
console.log(graph.match(undefined, rdf.type, pgo.Edge).size + " edges in the PG");
})
.finally(() => driver.close());
You can also provide a context in the form of a list of RDF/JS quads to drive the conversion.
// Property Graph API
import neo4j from 'neo4j-driver';
// Some useful RDF imports
import * as N3 from 'n3';
// PREC
import { cypherToRDF } from 'prec';
// Example Cypher query:
// create ( alice :PERSON { name: 'Alice' } ) -[:KNOWS]-> ( bob :PERSON { name: 'Bobby' } )
// Open the connection
const auth = neo4j.auth.basic('neo4j', 'password');
const driver = neo4j.driver('neo4j://localhost:7687/neo4j', auth);
// Context
const contextText = `
PREFIX prec: <http://bruy.at/prec#>
PREFIX pvar: <http://bruy.at/prec-trans#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/#>
PREFIX : <http://example.org></http:>
_:PersonRule a prec:PRSCNodeRule ;
prec:label "PERSON" ;
prec:propertyKey "name" ;
prec:produces
<< pvar:self a foaf:Person >> ,
<< pvar:self foaf:name "name"^^prec:valueOf >> .
_:CountryRule a prec:PRSCEdgeRule ;
prec:label "KNOWS" ;
prec:produces
<< pvar:source foaf:knows pvar:destination >> ,
<< pvar:self :occurrenceOf << pvar:source foaf:knows pvar:destination >> >> .
`
const contextQuads = new N3.Parser().parse(contextText);
// Build an RDF graph
cypherToRDF(driver, contextQuads)
.then(graph => {
// Print the RDF graph
console.log(new N3.Writer().quadsToString(graph.getQuads()));
})
.finally(() => driver.close());
// Expected output:
// _:node0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/#Person> .
// _:node0 <http://xmlns.com/foaf/0.1/#name> "Alice" .
// _:node0 <http://xmlns.com/foaf/0.1/#knows> _:node1 .
// _:node1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/#Person> .
// _:node1 <http://xmlns.com/foaf/0.1/#name> "Bobby" .
// _:edge0 <http://example.org/occurrenceOf> <<_:node0 <http://xmlns.com/foaf/0.1/#knows> _:node1>> .
Run npx prec -h
to have the full list of the current tools.
PG -> RDF
If you want to provide a context, use the --context path/to/your/context
option.
From the Cypher or the Gremlin API
npx prec cypher2rdf
translates Property Graphs from Neo4J to RDF. Thisnpx prec gremlin2rdf
translates “Tinkerpop enabled”From a JSON file:
npx prec apoc2rdf
and npx prec cypherJson2rdf
translates PropertyFrom an RDF graph:
npx prec applyContext
applies a context to an RDF graph previouslyRDF -> PG
npx prec prec2pg
allows to coming to Property Graphs from a RDFnpx prec apoc2rdf data/ex2_annlikesdan3.json > ignore/anndanRDF0.ttl
npx prec prec2pg print-cypher ignore/anndanRDF0.ttl
-c context.ttl
The easiest way to transform a Property Graph is by providing a Cypher or a
Gremlin connection, and optionally a context to get a nicer output.
If you do not provide any context, the produced RDF graph will be the “intermediate representation of the PG = PREC-0 graph”. If you have a PREC-0 graph, you can provide it to PREC later with a context to apply the context to the extracted PG.
You can also extract directly the graph from your Neo4J database.
npx prec cypher-to-rdf username password (uri-to-your-neo4j-instance) (-c=contextfile.ttl)
Default username should be neo4j and password is the one you entered when
creating the database. Default uri is the local instance with the default Neo4j
parameters.
Run a Cypher query like this one:
match (src)-[edge]->(dest) return src,edge,dest LIMIT 5
cypherJson2rdf
sub-command, for example if your output file is data\movies_cypher_all.json
npx prec cypherJson2rdf data\movies_cypher_all.json
You can also use the APOC plugin to extract the content of your Property Graph.
To export a Neo4J property graph from your database, you need to activate APOC file export:
set apoc.export.file.enabled=true
-> ApplyTo export the graph structure, use this Cypher instruction:CALL apoc.export.json.all("propertygraph.json",{useTypes:true})
npx prec apoc2rdf /path/to/your/propertygraph.json
will output thenpx prec gremlin2rdf (URI to connect to) [-c Context]
The default URI is the URI of a local TinkerPop Server.
PREC is licensed under the MIT License by Julian Bruyat / INSA Lyon
The repository includes code from other authors, also licensed under the MIT
License. See test/dataset/DatasetCore.test.js.