Aerospike Node.js用.lua文件注册UDF

时间:2019-01-24 09:39:34

标签: node.js lua aerospike

这是我的问题。

我已经注册了这样的模块

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文件中转储数据,或者只是检查流数据是否与我期望的相同

谢谢。

2 个答案:

答案 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' }