Aerospike提供能力来扫描数据库中的记录并通过用户定义函数(UDF)变更每条记录数据。
在SQL中,不带条件变更表中所有记录的UPDATE语句是:
UPDATE test.demo SET a = 1, b = 2, c = 3
Aeropike提供与上面SQL类似的功能,允许应用一个函数到每条记录,通过函数来变更记录数据。这个函数,被称作UDF(用户定义函数),被应用到单条记录。它可以提供参数,能读取和写入记录bin值与执行计算。
目前,扫描并应用UDF到每条记录只能在后台执行,就是说客户端把扫描请求发给数据库,但不用等待结果。扫描请求被放入队列,并且数据库中执行,没有结果返回到客户端。客户端会得到一个id,用来标识所发送扫描请求对应的任务,可用这个id检查扫描的状态。
除了能定义一个应用到每条记录的UDF,用于变更记录内容的扫描定义与正常的扫描定义相同,并且是使用后台扫描操作:aerospike_scan_background()。
我们象在【记录扫描】章节中所做的类似,先构建一个扫描对象,但不需要去选择bin,而且增加一个as_scan_apply_each()操作:
as_scan scan; as_scan_init(&scan, "test", "demo"); as_scan_apply_each(&scan, "mymodule", "mytransform", NULL);
解释:
The following is the mytransform" Record UDF, defined in
mymodule`. It is a pretty simple Record UDF, mimicking the SQL statement above.
下面所示是定义于模块mymodule中的UDF,名称是mytransform,它相当简单,模仿上述SQL语句的行为。
function mytransform(rec) rec['a'] = 1 rec['b'] = 2 rec['c'] = 3 aerospike:update(rec) end
A more elaborate function might be to increment "a", calculate "b" based on "a", and calculate "c" based on the values of "a" and "b":
稍微复杂点儿的函数可增加"a"、基于”a”计算”b",并基于"a"和“b“的数值计算”c”:
function mytransform(rec) rec['a'] = rec['a'] + 1 rec['b'] = rec['a'] * 2 rec['c'] = rec['a'] + rec['b'] aerospike:update(rec) end
此扫描可使用areospike_scan_background()执行:
uint64_t scan_id = 0; if (aerospike_scan_background(&as, &err, NULL, &scan, &scan_id) != AEROSPIKE_OK) { fprintf(stderr, "error(%d) %s at [%s:%d]\n", err.code, err.message, err.file, err.line); }
scan_id用来查询扫描的状态。scand_id为0是未定义,所以扫描操作将生成并设置scan_id的值。
可使用aerospike_scan_info()查询扫描的状态,状态信息将填充到一个as_scan_info对象中。
as_scan_info scan_info; if (aerospike_scan_info(&as, &err, NULL, scan_id, &scan_info) != AEROSPIKE_OK) { fprintf(stderr, "error(%d) %s at [%s:%d]\n", err.code, err.message, err.file, err.line); }