Skip to content

Query usage

This page describes how to use mutation queries such as add, property, drop, and merge operations. It explains general usage patterns for all mutation queries, and then highlights specific performance considerations. For details on how data consistency settings affect these queries, see transactions.

Basic mutation query usage

Aerospike Graph Service (AGS) supports several mutation operations that directly add, update, or remove data. Each call to these operations applies the change unconditionally, so repeating them adds new data, modifies properties again, or attempts to delete elements that may already be gone.

AddV and AddE queries

  • Insert a new vertex or edge every time the query runs. To prevent duplicates, enforce uniqueness using identifiers such as T.id.
Add vertices and edges (Python)
# Create Alice and Bob vertices
alice = g.add_v("person").property("name", "Alice").next()
bob = g.add_v("person").property("name", "Bob").next()
# Add an edge between Alice and Bob
g.add_e("knows").from_(alice).to(bob).iterate()

Property queries

  • Update properties on an existing vertex or edge.
  • Overwrite property values when called repeatedly, unless using multi-properties.
Update properties on a vertex (Python)
# Update the "age" property of an existing vertex
g.V().has("name", "Alice").property("age", 31).iterate()

Drop queries

  • Remove vertices, edges, or properties from the graph.
  • Determine what gets removed based on the final step in the traversal:
    • If the traversal ends on a vertex or edge, remove that element.
    • If it ends on a property, remove only that property.
    • Delete all edges connected to a vertex when that vertex is dropped.
Delete vertices or properties (Python)
# Drop a vertex and all its edges
g.V().has("name", "Alice").drop().iterate()
# Drop the nickname property from Bob
g.V().has("name", "Bob").properties("nickname").drop().iterate()

Use drop queries with caution and consider dependencies when removing vertices.

Merge queries

Merge operations such as mergeV and mergeE create a vertex or edge if it does not already exist, and update it if an on_match conditional is provided.

MergeV query

A merge vertex query consists of three parts:

  1. Search match (required) – Defines how to find an existing vertex, such as by T.id or specific properties.
  2. on_create (optional) – Properties applied only when the vertex does not exist and is created.
  3. on_match (optional) – Properties applied only when the vertex already exists.

In this example, person is the vertex label and name and age are properties. The search criteria use T.id, the first conditional creates the vertex with the name property, or the second conditional updates the age property when the vertex already exists.

Merge vertex (Python)
g.merge_v({T.id: "v1"})
.option(Merge.on_create, {T.label: "person", "name": "Alice"})
.option(Merge.on_match, {"age": 30})
.iterate()

Calling the same query multiple times does not create duplicate vertices. Conditionals defined in on_match are applied only to existing vertices.

MergeE query

A merge edge query also has three parts:

  1. Search match (required) – Defines how to find an existing edge, such as by its label and connected vertices.
  2. on_create (optional) – Properties applied only when the edge does not exist and is created.
  3. on_match (optional) – Properties applied only when the edge already exists between the vertices.

In this example, knows is the edge label and since and weight are edge properties. The search criteria use the edge label and vertex directions, the first conditional creates the edge with the since property, or the second conditional adds or updates the weight property when the edge already exists.

Merge edge (Python)
g.merge_e({T.label: "knows", Direction.IN: "v1", Direction.OUT: "v2"})
.option(Merge.on_create, {"since": 2020})
.option(Merge.on_match, {"weight": 5})
.iterate()

When running mergeE, terminate with iterate(). Using next() will read the adjacent vertices again to return the edge. If you only need the edge ID, use id().next():

g.merge_e({T.label: "knows", Direction.IN: "v1", Direction.OUT: "v2"})
.option(Merge.on_create, {"since": 2020})
.option(Merge.on_match, {"weight": 5})
.id()
.next()

mergeE also supports Merge.inV and Merge.outV options to set which vertices the edge should connect, which is helpful when the vertices are chosen earlier in the traversal instead of being provided directly:

Merge edge with in/out vertex options (Java)
// Earlier step: find Alice and label her as "a"
g.V().has("name", "Alice").as("a")
// Earlier step: find Bob and label him as "b"
.V().has("name", "Bob").as("b")
// Merge an edge with Alice as OUT and Bob as IN
.mergeE(asMap(T.label, "knows", Direction.OUT, Merge.outV, Direction.IN, Merge.inV))
.option(Merge.outV, select("a")) // Later step: use Alice as OUT vertex
.option(Merge.inV, select("b")) // Later step: use Bob as IN vertex

Performance

Merging edges on supernodes (vertices with many connected edges) triggers secondary index lookups. These lookups consume query threads and may impact performance. This is most relevant when the search uses only one direction (IN or OUT) rather than both (IN and OUT).

By default, Aerospike has 128 query threads. Each index query uses 4 threads limiting you to 32 parallel index queries (128 divided by 4). Exceeding this limit results in the following error:

Operation not allowed at this time

Reduce merges on supernodes, or limit the number of parallel merges, to stay within the available query threads. For more information, see supernodes.

Reliability

Certain conditions can affect how merges behave:

  • If the identifiers used for merging, such as vertex label or property value, are not unique, merges can create duplicates or update the wrong element.

  • mergeV and mergeE apply to all elements matching the search criteria. For example, this query updates every vertex labeled "person":

    g.mergeV(asMap(T.label, "person"))
    .option(Merge.on_match, asMap("updated", true))
    .iterate()

    Include unique identifiers in the search match to avoid unintended bulk updates.

Feedback

Was this page helpful?

What type of feedback are you giving?

What would you like us to know?

+Capture screenshot

Can we reach out to you?