openCypher in Gaffer
Warning
The openCypher API is still experimental, it is provided by a translation layer to Gremlin from the OpenCypher project. Due to this, the implementation may experience the same limitations as the Gremlin API. It's performance is unknown but likely slower than Gremlin or Standard Gaffer Operations.
openCypher Querying
Generally the syntax and features of using openCypher in Gaffer are the same as using Cypher in other graph databases. Most of the features you will have used in standard Cypher should be available. The layer in Gaffer targets openCypher v9 meaning any features outside of that version cannot be guaranteed.
Full guides on querying using Cypher are available elsewhere however, a few useful queries to get you started are available here. Translation of what exact Gremlin query this maps to is provided.
Seeded vertex query using string IDs.
Seeded edge query using string IDs.
Filtering on group and properties.
g.V().as('n').hasLabel('person').has('full-name', containing('John')).where(__.constant(25d).map(cypherToInteger()).is(neq(' cypher.null')).as(' GENERATED1').select('n').values('age').where(gt(' GENERATED1'))).select('n').project('n').by(__.choose(neq(' cypher.null'), __.valueMap().with('~tinkerpop.valueMap.tokens'))).toList()
Transform and project on properties.
g.V().as('n').project('(n.age * 1000)', 'reverse(n.name)').by(__.constant(1000).as('__GENERATED1').select('n').choose(neq(' cypher.null'), __.choose(__.values('age'), __.values('age'), __.constant(' cypher.null'))).choose(__.or(__.is(eq(' cypher.null')), __.select('__GENERATED1').is(eq(' cypher.null'))), __.constant(' cypher.null'), __.math('_ * __GENERATED1'))).by(__.choose(neq(' cypher.null'), __.choose(__.values('name'), __.values('name'), __.constant(' cypher.null'))).map(cypherReverse())).toList()
Limitations and Considerations
There are a few limitations you need to be aware of using this API. Generally these stem from the translation layer but are also due to a fundamental difference in the way Gaffer and Cypher are intended to be used.
- If using the
with()
step all numbers are longs by default you need to specifically change them to integers if required e.g.toInteger(1)
. You can also change them to floats withtoFloat(1.2)
. - How data is returned is different to normal Gremlin. It will be returned as
key value maps where each
RETURN
in the cypher query is a key. - Currently the version of the openCypher translator is stuck at v1.0.0 due to
the Gaffer scala version. This means not all features of openCypher are
available e.g. no
replace()
function. The reference guide attempts to document all custom Cypher functions available. - Need to be considerate of how it maps to Gremlin and Gaffer as something like
this:
MATCH (n) WHERE (n:person OR n:software)
will do aGetAllElements
with nothing in the Gaffer View. In this case you should use anOPTIONAL MATCH
instead. - Gaffer groups or properties with a
-
in require wrapping in back ticks.