Skip to content

Apply a UDF

For the complete documentation index see: llms.txt

All documentation pages available in markdown.

Applies to

  • Aerospike Developer SDK preview (Java 21+ and Python 3.10+)
  • Aerospike Database 6.0 or later unless a section states otherwise

Record UDFs run on a single record. The record may already exist or be created by the UDF. Register the Lua module on the cluster first. See Manage UDFs.

Except where noted, snippets on this page use the imports below. A snippet lists additional import lines only when it needs a type not shown here. When this page includes a Complete example section, that block is fully self-contained with every import required to run it.

import com.aerospike.client.sdk.DataSet;
import com.aerospike.client.sdk.Key;
import com.aerospike.client.sdk.RecordStream;
import com.aerospike.client.sdk.Session;
import java.util.Optional;

Invoke a UDF on one record

Chain executeUdf() / execute_udf(), function(), optional passing(), and execute(). The server passes the record as the first argument to the Lua function; values in passing() follow.

readBin function

The following Lua runs on the server and is shared by both the Java and Python examples. Define it in example.lua (see Manage UDFs):

function readBin(r, name)
return r[name]
end

readBin returns the value of bin name on record r.

DataSet udfDemo = DataSet.of("test", "udf_demo");
Key key = udfDemo.id("demo:1");
session.upsert(key).bin("name").setTo("Aerospike").execute();
RecordStream rs = session.executeUdf(key)
.function("example", "readBin")
.passing("name")
.execute();
Optional<Object> value = rs.getFirstUdfResult();
System.out.println(value.orElse(null));

📖 API reference: Session.executeUdf | RecordStream.getFirstUdfResult

Multiple arguments

When the UDF accepts extra parameters, pass them with passing().

multiplyAndAdd function

The following Lua runs on the server and is shared by both the Java and Python examples. Define it in example.lua (see Manage UDFs):

function multiplyAndAdd(r, a, b)
return r['factor'] * a + b
end

multiplyAndAdd multiplies the record’s factor bin by a and adds b, so here 3 * 10 + 5 = 35.

DataSet udfDemo = DataSet.of("test", "udf_demo");
Key key = udfDemo.id("demo:2");
session.upsert(key).bin("factor").setTo(3).execute();
RecordStream rs = session.executeUdf(key)
.function("example", "multiplyAndAdd")
.passing(10, 5)
.execute();
Optional<Object> result = rs.getFirstUdfResult();
System.out.println(result.orElse(null)); // 35

Batch UDF

Pass multiple keys to run the same function on each record.

DataSet udfDemo = DataSet.of("test", "udf_demo");
Key k1 = udfDemo.id("demo:10");
Key k2 = udfDemo.id("demo:11");
session.upsert(k1).bin("name").setTo("Alice").execute();
session.upsert(k2).bin("name").setTo("Bob").execute();
RecordStream rs = session.executeUdf(k1, k2)
.function("example", "readBin")
.passing("name")
.execute();
while (rs.hasNext()) {
var rr = rs.next();
System.out.println(rr.udfResultOrThrow());
}

Complete example: register, write, and read

This example registers example.lua, writes a record, and invokes readBin.

import com.aerospike.client.sdk.Cluster;
import com.aerospike.client.sdk.ClusterDefinition;
import com.aerospike.client.sdk.DataSet;
import com.aerospike.client.sdk.Key;
import com.aerospike.client.sdk.RecordStream;
import com.aerospike.client.sdk.Session;
import com.aerospike.client.sdk.policy.Behavior;
import com.aerospike.client.sdk.task.RegisterTask;
import java.util.Optional;
public class UdfReadBinExample {
private static final String EXAMPLE_LUA = """
function readBin(r, name)
return r[name]
end
function multiplyAndAdd(r, a, b)
return r['factor'] * a + b
end
""";
public static void main(String[] args) {
try (Cluster cluster = new ClusterDefinition("localhost", 3000).connect()) {
Session session = cluster.createSession(Behavior.DEFAULT);
RegisterTask task = session.registerUdfString(EXAMPLE_LUA, "example.lua");
task.waitTillComplete();
DataSet udfDemo = DataSet.of("test", "udf_demo");
Key key = udfDemo.id("demo:1");
session.upsert(key).bin("name").setTo("Aerospike").execute();
RecordStream rs = session.executeUdf(key)
.function("example", "readBin")
.passing("name")
.execute();
Optional<Object> value = rs.getFirstUdfResult();
System.out.println(value.orElse(null));
}
}
}

Complete example: multiplyAndAdd

import com.aerospike.client.sdk.Cluster;
import com.aerospike.client.sdk.ClusterDefinition;
import com.aerospike.client.sdk.DataSet;
import com.aerospike.client.sdk.Key;
import com.aerospike.client.sdk.RecordStream;
import com.aerospike.client.sdk.Session;
import com.aerospike.client.sdk.policy.Behavior;
import com.aerospike.client.sdk.task.RegisterTask;
import java.util.Optional;
public class UdfMultiplyAndAddExample {
private static final String EXAMPLE_LUA = """
function multiplyAndAdd(r, a, b)
return r['factor'] * a + b
end
""";
public static void main(String[] args) {
try (Cluster cluster = new ClusterDefinition("localhost", 3000).connect()) {
Session session = cluster.createSession(Behavior.DEFAULT);
RegisterTask task = session.registerUdfString(EXAMPLE_LUA, "example.lua");
task.waitTillComplete();
DataSet udfDemo = DataSet.of("test", "udf_demo");
Key key = udfDemo.id("demo:2");
session.upsert(key).bin("factor").setTo(3).execute();
RecordStream rs = session.executeUdf(key)
.function("example", "multiplyAndAdd")
.passing(10, 5)
.execute();
Optional<Object> result = rs.getFirstUdfResult();
System.out.println(result.orElse(null));
}
}
}

Complete example: inline writeUnique

Register unique.lua from a string, invoke writeUnique twice on the same key, and observe that the second call does not overwrite an existing record. See Manage UDFs for the writeUnique definition.

import com.aerospike.client.sdk.Cluster;
import com.aerospike.client.sdk.ClusterDefinition;
import com.aerospike.client.sdk.DataSet;
import com.aerospike.client.sdk.Key;
import com.aerospike.client.sdk.Record;
import com.aerospike.client.sdk.RecordResult;
import com.aerospike.client.sdk.RecordStream;
import com.aerospike.client.sdk.Session;
import com.aerospike.client.sdk.policy.Behavior;
import com.aerospike.client.sdk.task.RegisterTask;
public class UdfWriteUniqueExample {
private static final String UNIQUE_LUA = """
function writeUnique(r, name, value)
if not aerospike:exists(r) then
aerospike:create(r)
r[name] = value
aerospike:update(r)
end
end
""";
public static void main(String[] args) {
try (Cluster cluster = new ClusterDefinition("localhost", 3000).connect()) {
Session session = cluster.createSession(Behavior.DEFAULT);
RegisterTask task = session.registerUdfString(UNIQUE_LUA, "unique.lua");
task.waitTillComplete();
DataSet udfDemo = DataSet.of("test", "udf_demo");
Key key = udfDemo.id("demo:3");
session.delete(key).execute();
for (int i = 0; i < 2; i++) {
session.executeUdf(key)
.function("unique", "writeUnique")
.passing("status", "created")
.execute();
}
RecordStream rs = session.query(key).execute();
RecordResult rr = rs.next();
Record rec = rr.recordOrThrow();
System.out.println(rec.getString("status"));
}
}
}
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?