使用 .lua 文件在 Aerospike Node.js 上注册 UDF

以下是我的问题。

我已经像下面这样注册模块

asclient.client.udfRegister('./lua/lm.lua', function (error) {
  if (error) {
    console.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文件中的数据或者只是检查流数据是否与我预期的相同

谢谢。

点赞
用户1917187
用户1917187

我建议检查一下你的apply()调用。我认为应该是client.query.apply()。我没有看到UDF中显然有什么问题。我认为client.apply() 是针对操作单个记录并可以更改它们的recordUDFs。它们没有map()方法。对于你正在编写的流UDFs,query.apply()将支持map()。

2019-01-24 16:36:38
用户1573115
用户1573115

如果您想要使用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' }
2019-01-28 14:46:16