Apply a UDF
Single record
UDFs that execute on a single record are Record UDFs. The record may or may not exist in the database, which allows the UDF to update or create a record.
To invoke a Record UDF using Client.execute_udf
:
Client.execute_udf( key, packageName, functionName, args = [], opts = {})
Where:
key
— The key of the record on which to invoke the function.packageName
— The UDF module that contains the function to invoke.functionName
— The function to invoke.args
— The function arguments.opts
— The policy options.
This example defines a UDF in the module examples.lua:
function readBin(r, name) return r[name]end
readBin
returns the value of record r in bin name.
The client application can invoke readBin
on a record:
result = client.execute_udf(key, "examples", "readBin", ["name"])
key
specifies the record to pass to the UDF as the parameter r
.
Multiple Arguments
If the UDF accepts multiple arguments, add each argument to Client.execute_udf
.
For example, if the following UDF is defined in example.lua:
function multiplyAndAdd(r, a, b) return r['factor'] * a + b;end
(This multiplies the bin factor by a and adds b, and returns results to the caller.)
Then, to invoke multiplyAndAdd()
from Ruby, run:
result = client.execute_udf(key, "examples", "multiplyAndAdd", [10, 5])
Transform
Use the Aerospike Ruby client ability to scan records in the database and transform each record using User-Defined Functions (UDFs).
In SQL, you perform transformation on all rows in a table as an UPDATE statement without predicates:
UPDATE test.demoSET a = 1, b = 2WHERE c = 3
Aerospike provides a similar capability, but allows you to transform records by applying a Record UDF function on each record. A Record UDF is applied to individual records. It can be provided as arguments, and can read and write the bins of a record and perform calculation. Refer to the QueryExecute
example in the examples package.
Defining Record UDFs
The following is the processRecord
Record UDF defined in record_example.lua, where:
- The record contains two integer bins: name1 and name2.
- For name1 even integers, add the value to the existing name1 bin.
- For name1 integers with a multiple of 5, delete the name2 bin.
- For name1 integers with a multiple of 9, delete the record.
function processRecord(r, name1, name2, addValue) local v = r[name1]
if (v % 9 == 0) then aerospike:remove(r) return end
if (v % 5 == 0) then r[name2] = nil aerospike:update(r) return end
if (v % 2 == 0) then r[name1] = v + addValue aerospike:update(r) endend
Registering UDFs
After defining the UDF function, it must register with the Aerospike cluster. See Register UDF.
Initializing the Query Statement
To initialize a query statement:
stmt = Statement.new(namespace, set, [binName1])stmt.filters << Filter.Range(binName1, begin, end)
Executing a UDF on a Record
To execute UDFs using #execute_udf_on_query
:
task = client.execute_udf_on_query(stmt, 'record_example', 'processRecord', [binName1, binName2, 100])
Where,
stmt
— Specifies the set of records for the UDF.record_example
— Specifies the UDF module.processRecord
— Specifies the function to use on each record.- These parameters passthrough to the UDF function:
name1
,name2
, andaddValue
.
Determining UDF Processing Status
To inform the application of job status, call #wait_till_completed
in the task periodically:
# to block until the UDF is run on all records in querytask.wait_till_completed# task is completed successfully