这是我的问题。
我已经注册了这样的模块
asclient.client.udfRegister('./lua/lm.lua', function (error) {
if (error) {
console.error('Error: %s [%d]', error.message, error.code)
}
});
代码平安后,我检查模块是否正确注册
aql> show modules
,输出为
| "lm.lua" | "824bf77bff0f8b35c4eacc5ddcee82b1802a0c63" | "LUA" |
所以我很确定模块已经加载
然后我尝试在该lm.lua文件中应用一些功能
var ctoken = '0878d655bd4c438236b060b9b1c1d2af';
var key = new Key('namespace', 'set', 12345)
var udf = { module: 'lm', funcname: 'getlm', args: [ctoken]}
asquery.client.apply(key, udf, function (error, result) {
if (error) throw error
console.log(result);
});
lua文件的内容为
function getlm(stream, conv)
local function transformer(rec)
local touple = map()
touple["1"] = rec["1"]
touple["2"] = rec["2"]
touple["3"] = rec["3"]
return touple
end
return stream:map(transformer)
end
基本上,我映射了AS中的所有字段,只是想返回一些结果以确保其正常工作,但是出于某种原因总是返回
AerospikeError: /opt/aerospike/usr/udf/lua/lm.lua:17: attempt to call method 'map' (a nil value)
有什么方法可以在此.lua文件中转储数据,或者只是检查流数据是否与我期望的相同
谢谢。
答案 0 :(得分:2)
我建议检查您对apply()的调用。我认为应该是client.query.apply()。我没有发现udf明显有问题。我认为client.apply()适用于对单个记录进行操作并可以更改它们的recordUDF。他们没有map()方法。对于您正在编写的流UDF,query.apply()将支持map()。
答案 1 :(得分:2)
如果要使用client.apply()
方法将UDF应用于单个记录,则需要将getlm
函数重写为Record UDF。 (如@pgupta所指出。)
示例:
demo.lua:
function getlm(rec)
local tuple = map()
tuple["1"] = rec["1"]
tuple["2"] = rec["2"]
tuple["3"] = rec["3"]
return tuple
end
apply.js:
const Aerospike = require('aerospike')
Aerospike
.connect()
.then(async client => {
await client.udfRegister('demo.lua').then(job => job.wait())
const key = new Aerospike.Key('test', 'test', 'test')
await client.put(key, { '1': 'foo', '2': 'bar', '3': 'fox' })
const udf = { module: 'demo', funcname: 'getlm'}
const result = await client.apply(key, udf)
console.info(result)
client.close()
})
.catch(error => {
console.error(error)
if (error.client) error.client.close()
})
$ node apply.js
{ '1': 'foo', '2': 'bar', '3': 'fox' }