Gremlin standards compliance in Amazon Neptune
The following sections provide an overview of the Neptune implementation of Gremlin and how it differs from the Apache TinkerPop implementation.
Neptune implements some Gremlin steps natively in its engine, and uses the Apache TinkerPop Gremlin implementation to process others (see Native Gremlin step support in Amazon Neptune). The following sections provide an overview of cases where Neptune's implementation differs from the TinkerPop implementation.
Applicable Standards for Gremlin
-
The Gremlin language is defined by Apache TinkerPop Documentation
and the Apache TinkerPop implementation of Gremlin rather than by a formal specification. -
For numeric formats, Gremlin follows the IEEE 754 standard (IEEE 754-2019 - IEEE Standard for Floating-Point Arithmetic
. For more information, also see the Wikipedia IEEE 754 page).
Neptune Gremlin Implementation Differences
There are a few important differences between the Amazon Neptune implementation of Gremlin and the implementation defined by Apache TinkerPop.
For some concrete examples of these implementation differences shown in Gremlin Console and Amazon Neptune, see the Using Gremlin to Access the Graph section of the Quick Start.
The following is a list of implementation differences:
Topics
- Pre-Bound Variables
- TinkerPop Enumerations
- Java Code
- Date and Time
- Script Execution
- Sessions
- Transactions
- Vertex and Edge IDs
- User-Supplied IDs
- Vertex Property IDs
- Cardinality of Vertex Properties
- Updating a Vertex Property
- Labels
- Variables
- Timeouts
- Escape Characters
- Groovy Limitations
- Serialization
- Lambda Steps
- Unsupported Gremlin Methods
- Unsupported Gremlin Steps
- Other Features
- Gremlin Graph Supported Features
Pre-Bound Variables
The traversal object g
is Pre-bound. The graph
object is not
supported.
TinkerPop Enumerations
Neptune does not support fully qualified class names for enumeration values. For
example, you must use single
and not
org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality.single
in
your Groovy request.
The enumeration type is determined by parameter type.
The following table shows the allowed enumeration values and the related TinkerPop fully qualified name.
Allowed Values | Class |
---|---|
id , key , label , value |
org.apache.tinkerpop.gremlin.structure.T |
T.id , T.key , T.label , T.value |
org.apache.tinkerpop.gremlin.structure.T |
set , single |
org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality |
decr , incr , shuffle
|
|
Order.decr , Order.incr , Order.shuffle
|
org.apache.tinkerpop.gremlin.process.traversal.Order |
global , local
|
|
Scope.global , Scope.local
|
org.apache.tinkerpop.gremlin.process.traversal.Scope |
all , first , last , mixed |
|
normSack |
org.apache.tinkerpop.gremlin.process.traversal.SackFunctions.Barrier |
addAll , and , assign , div ,
max , min , minus , mult ,
or , sum , sumLong
|
|
keys , values |
|
BOTH , IN , OUT |
|
any , none |
org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent.Pick |
Java Code
Neptune does not support calls to methods defined by arbitrary Java or Java library
calls other than supported Gremlin APIs. For example, java.lang.*
,
Date()
, and g.V().tryNext().orElseGet()
are not allowed.
Date and Time
Neptune provides the datetime
method for specifying dates and times for
queries sent in the Gremlin Groovy variant. This includes
the Gremlin Console, text strings using the HTTP REST API, and any other serialization
that
uses Groovy. A date and time value must be specified with the datetime()
function.
This only applies to methods where you send the Gremlin query as a text string. If you are using a Gremlin Language Variant (GLV), you must use the native date classes and functions for the language. For more information, see the Best Practices section, Using Native Date and Time for GLV Time Data.
The datetime( )
function takes a string value with an ISO-8601 compliant
datetime up to millisecond precision. For example,
datetime('2018-01-01T00:00:00')
.
Some examples of ISO-8601 datetime formats are as follows:
-
YYYY-MM-DD
-
YYYY-MM-DDTHH:mm
-
YYYY-MM-DDTHH:mm:SS
-
YYYY-MM-DDTHH:mm:SS.ssss
-
YYYY-MM-DDTHH:mm:SSZ
If you enter a datetime value in your graph that has an explicit time zone specified, and later query that value, the value is returned in Coordinated Universal Time (UTC) without any time-zone information.
The reason for this is that Neptune transforms and stores all dates and times as UTC so that they can be compared efficiently. This is important for performance, but results in the loss of information about the originating time zone.
Script Execution
All queries must begin with g
, the traversal object.
In String query submissions, multiple traversals can be issued separated by a semicolon
(;
) or a newline character (\n
). To be executed, every statement
other than the last must end with an .iterate()
step. Only the final traversal
data is returned. Note that this does not apply to GLV ByteCode query submissions.
Sessions
Sessions in Neptune are limited to only 10 minutes in duration. See Gremlin sessions
and the TinkerPop
Session Reference
Transactions
Neptune opens a new transaction at the beginning of each Gremlin traversal and closes the transaction upon the successful completion of the traversal. The transaction is rolled back when there is an error.
Multiple statements separated by a semicolon (;
) or a newline character
(\n
) are included in a single transaction. Every statement other than the last
must end with a next()
step to be executed. Only the final traversal data is
returned.
Manual transaction logic using tx.commit()
and tx.rollback()
is not supported.
Vertex and Edge IDs
Neptune Gremlin Vertex and Edge IDs must be of type String
. If you don't
supply an ID when you add a vertex or an edge, a UUID is generated and converted to
a
string; for example, "48af8178-50ce-971a-fc41-8c9a954cea62"
.
This means that user-supplied IDs are supported, but they are optional in normal usage.
However, the Neptune Load
command requires that all IDs be specified using
the ~id field in the Neptune CSV format.
User-Supplied IDs
User-supplied IDs are allowed in Neptune Gremlin with the following stipulations.
-
Supplied IDs are optional.
-
Only vertexes and edges are supported.
-
Only type
String
is supported.
To create a new vertex with a custom ID, use the property
step with the
id
keyword: g.addV().property(id, 'customid')
.
Do not put quotation marks around the id
keyword.
All vertex IDs must be unique, and all edge IDs must be unique. However, Neptune does allow a vertex and an edge to have the same ID.
If you try to create a new vertex using the g.addV()
and a vertex with that
ID already exists, the operation fails. The exception to this is if you specify a
new label
for the vertex, the operation succeeds but adds the new label and any additional properties
specified to the existing vertex. Nothing is overwritten. A new vertex is not created.
The
vertex ID does not change and remains unique.
For example, the following Gremlin Console commands succeed:
gremlin> g.addV('label1').property(id, 'customid') gremlin> g.addV('label2').property(id, 'customid') gremlin> g.V('customid').label() ==>label1::label2
Vertex Property IDs
Vertex property IDs are generated automatically and can show up as positive or negative numbers when queried.
Cardinality of Vertex Properties
Neptune supports set cardinality and single cardinality. If it isn't specified, set
cardinality is selected. This means that if you set a property value, it adds a new
value to
the property, but only if it doesn't already appear in the set of values. This is
the Gremlin
enumeration value of Set
List
is not supported. For more information about property cardinality, see
the Vertex
Updating a Vertex Property
To update a property value without adding an additional value to the set of values,
specify single
cardinality in the property
step.
g.V('exampleid01').property(single, 'age', 25)
This removes all existing values for the property.
Labels
Neptune supports multiple labels for a vertex. When you create a label, you can
specify multiple labels by separating them with ::
. For example,
g.addV("Label1::Label2::Label3")
adds a vertex with three different labels.
The hasLabel
step matches this vertex with any of those three labels:
hasLabel("Label1")
, hasLabel("Label2")
, and
hasLabel("Label3")
.
The ::
delimiter is reserved for this use only. You cannot specify multiple
labels in the hasLabel
step. For example,
hasLabel("Label1::Label2")
does not match anything.
Variables
Neptune does not support Gremlin variables and does not support the
bindings
property.
Timeouts
The Gremlin Console command :remote config timeout
sets the local timeout
only. To set the remote query timeout for Neptune, use the
neptune_query_timeout
parameter. For more information, see Amazon Neptune DB Parameter Groups.
Escape Characters
Neptune resolves all escape characters as described in the Escaping Special
Characters
Groovy Limitations
Neptune doesn't support Groovy commands that don't start with g
. This
includes math (for example, 1+1
), system calls (for example,
System.nanoTime()
), and variable definitions (for example,
1+1
).
Neptune does not support fully qualified class names. For example, you must use
single
and not
org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality.single
in
your Groovy request.
Serialization
Neptune supports the following serializations based on the requested MIME type.
MIME type | Serialization | Configuration |
|
GryoMessageSerializerV1d0 |
ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1d0] |
|
GryoMessageSerializerV1d0 |
serializeResultToString: true} |
application/vnd.gremlin-v3.0+gryo |
GryoMessageSerializerV3d0 |
ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0] |
|
GryoMessageSerializerV3d0 |
serializeResultToString: true |
|
GraphSONMessageSerializerGremlinV1d0 |
ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV1d0] |
|
GraphSONMessageSerializerGremlinV2d0 |
ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV2d0] |
|
|
|
|
GraphSONMessageSerializerV3d0 |
ioRegistries: [org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerIoRegistryV3d0] |
|
GraphBinaryMessageSerializerV1 |
|
Lambda Steps
Neptune does not support Lambda Steps.
Unsupported Gremlin Methods
Neptune does not support the following Gremlin methods:
-
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.program(org.apache.tinkerpop.gremlin.process.computer.VertexProgram)
-
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.sideEffect(java.util.function.Consumer)
-
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.from(org.apache.tinkerpop.gremlin.structure.Vertex)
-
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.to(org.apache.tinkerpop.gremlin.structure.Vertex)
For example, the following traversal is not allowed:
g.V().addE('something').from(g.V().next()).to(g.V().next())
.
Unsupported Gremlin Steps
Neptune does not support the following Gremlin steps:
-
The Gremlin io( ) Step
is not supported in Neptune. For example, the query g.io("graph.xml").read().iterate()
would not work with Neptune.
Other Features
The Neptune implementation of Gremlin does not expose the graph
object.
The following section describes the supported and unsupported graph
features.
Gremlin Graph Supported Features
The following is a set of features as implemented by the Neptune Gremlin graph. These
features are the same as would be returned by the graph.features()
command.
Graph Feature | Enabled |
---|---|
Transactions |
true |
ThreadedTransactions |
false |
Computer |
false |
Persistence |
true |
ConcurrentAccess |
true |
Variable Feature | Enabled |
---|---|
Variables |
false |
SerializableValues |
false |
UniformListValues |
false |
BooleanArrayValues |
false |
DoubleArrayValues |
false |
IntegerArrayValues |
false |
StringArrayValues |
false |
BooleanValues |
false |
ByteValues |
false |
DoubleValues |
false |
FloatValues |
false |
IntegerValues |
false |
LongValues |
false |
MapValues |
false |
MixedListValues |
false |
StringValues |
false |
ByteArrayValues |
false |
FloatArrayValues |
false |
LongArrayValues |
false |
Vertex Feature | Enabled |
---|---|
MetaProperties |
false |
DuplicateMultiProperties |
false |
AddVertices |
true |
RemoveVertices |
true |
MultiProperties |
true |
UserSuppliedIds |
true |
AddProperty |
true |
RemoveProperty |
true |
NumericIds |
false |
StringIds |
true |
UuidIds |
false |
CustomIds |
false |
AnyIds |
false |
Vertex Property Feature | Enabled |
---|---|
UserSuppliedIds |
false |
AddProperty |
true |
RemoveProperty |
true |
NumericIds |
true |
StringIds |
true |
UuidIds |
false |
CustomIds |
false |
AnyIds |
false |
Properties |
true |
SerializableValues |
false |
UniformListValues | false |
BooleanArrayValues |
false |
DoubleArrayValues |
false |
IntegerArrayValues |
false |
StringArrayValues |
false |
BooleanValues |
true |
ByteValues |
true |
DoubleValues |
true |
FloatValues |
true |
IntegerValues |
true |
LongValues |
true |
MapValues |
false |
MixedListValues |
false |
StringValues |
true |
ByteArrayValues |
false |
FloatArrayValues |
false |
LongArrayValues |
false |
Edge Feature | Enabled |
---|---|
AddEdges |
true |
RemoveEdges |
true |
UserSuppliedIds |
true |
AddProperty |
true |
RemoveProperty |
true |
NumericIds |
false |
StringIds |
true |
UuidIds |
false |
CustomIds |
false |
AnyIds |
false |
Edge Property Feature | Enabled |
---|---|
Properties |
true |
SerializableValues |
false |
UniformListValues |
false |
BooleanArrayValues |
false |
DoubleArrayValues |
false |
IntegerArrayValues |
false |
StringArrayValues |
false |
BooleanValues |
true |
ByteValues |
true |
DoubleValues |
true |
FloatValues |
true |
IntegerValues |
true |
LongValues |
true |
MapValues |
false |
MixedListValues |
false |
StringValues |
true |
ByteArrayValues |
false |
FloatArrayValues |
false |
LongArrayValues |
false |