Aerospike NodeJS UDF 聚合错误
Aerospike NodeJS UDF Aggregation Error
我创建了一个聚合函数,它在 aerospike 中工作,在 AQL 中工作:
AGGREGATE filter2.check_teamId('123', 0, 1456499994597) ON analytics.tracking
WHERE teamId = '123'
这 returns 结果。
然后我尝试在 NodeJS 中使用相同的 UDF:
var statement = {
aggregationUDF: {module: 'filter2', funcname: 'check_teamId',
arg:['123', 0, 1456499994597]}
};
var query = client.query('analytics', 'tracking', statement);
var stream = query.execute();
结果是一个看似无意义的错误:
{ code: 100,
message: 'UDF: Execution Error 1',
func: 'as_query_aggregate',
file: 'src/main/aerospike/aerospike_query.c',
line: 903 }
服务器记录状态:
Feb 28 2016 22:33:58 GMT: INFO (scan): (scan.c::933) starting
aggregation scan job 1201452721893048027 {analytics:tracking}
priority 2
Feb 28 2016 22:33:58 GMT: INFO (scan): (scan.c::1026)
finished aggregation scan job 1201452721893048027 (0)
有没有人有任何让 UDF 与 NodeJS 一起工作的技巧?
或者有什么想法可以诊断错误吗?
我已经在配置中设置了不影响结果的用户 UDF 位置。
更新:
这是 lua 代码:
local function map_profile(record)
return map {interaction=record.interaction,
teamId=record.teamId, datetime=record.datetime,
timestamp=record.timestamp, version=record.version,
interactions=record.interactions}
end
function check_teamId(stream, teamId, startDate, endDate)
local function filter_teamId(record)
return record.teamId == teamId and
record.timestamp >= startDate and record.timestamp <= endDate
end
return stream : filter(filter_teamId) : map(map_profile)
end
您遇到 UDF 执行错误(代码:100)的最可能原因是 LUA 子系统的系统 and/or 用户路径设置不正确。如果您为客户端打开调试日志记录,您可能会看到以下一条或两条错误消息:
Apr 04 2016 08:15:19 UTC: DEBUG(45951) [conversions.cc:248] [config_from_jsobject] - Could not find a valid LUA system path ./aerospike-client-c/package/usr/local/aerospike/client/sys/udf/lua/
Apr 04 2016 08:15:19 UTC: DEBUG(45951) [conversions.cc:273] [config_from_jsobject] - Could not find valid LUA user path ./aerospike-client-c/package/usr/local/aerospike/client/usr/udf/lua
如果客户端无法自动确定正确的路径,则必须在配置中传递system/user路径。 (见下文。)
但是您在 Node.js 客户端中的 UDF 调用还有另一个问题。 UDF 的参数应该在 aggregationUDF
对象的 args
元素中传递,而不是在 arg
.
中传递
这是一个适合我的完整示例:
const Aerospike = require('aerospike')
const config = {
hosts: '192.168.33.10:3000',
log: { level: 5 },
modlua: {
userPath: './',
systemPath: './node_modules/aerospike/aerospike-client-c/lua/'
}
}
Aerospike.connect(config, (error, client) => {
if (error) throw error
var statement = {
aggregationUDF: {
module: 'agg',
funcname: 'check_teamId',
args: ['123', 0, 1456499994597]
}
}
var query = client.query('test', 'tracking', statement)
var stream = query.execute()
var count = 0
stream.on('error', (error) => console.error('error:', error))
stream.on('data', (result) => {
count++
console.log('result:', result)
})
stream.on('end', () => {
console.log('found %d records', count)
client.close()
})
})
请注意,此示例使用的 aerospike@2.0.0-alpha.1
客户端版本仅为 released。但是 UDF 查询的设置和执行与 v1.x 客户端相同。
我也把这个例子上传到Github here。此 Gist 还包含一个 setup.js
脚本,用于根据您的 map_profile
函数的预期创建一些示例记录。
欢迎在我们的 user forum 中跟进此事。我很想知道您是否将其用于您的应用程序。 (或有关 Aerospike Node.js 客户端的任何其他反馈!)
我创建了一个聚合函数,它在 aerospike 中工作,在 AQL 中工作:
AGGREGATE filter2.check_teamId('123', 0, 1456499994597) ON analytics.tracking
WHERE teamId = '123'
这 returns 结果。 然后我尝试在 NodeJS 中使用相同的 UDF:
var statement = {
aggregationUDF: {module: 'filter2', funcname: 'check_teamId',
arg:['123', 0, 1456499994597]}
};
var query = client.query('analytics', 'tracking', statement);
var stream = query.execute();
结果是一个看似无意义的错误:
{ code: 100,
message: 'UDF: Execution Error 1',
func: 'as_query_aggregate',
file: 'src/main/aerospike/aerospike_query.c',
line: 903 }
服务器记录状态:
Feb 28 2016 22:33:58 GMT: INFO (scan): (scan.c::933) starting aggregation scan job 1201452721893048027 {analytics:tracking} priority 2
Feb 28 2016 22:33:58 GMT: INFO (scan): (scan.c::1026) finished aggregation scan job 1201452721893048027 (0)
有没有人有任何让 UDF 与 NodeJS 一起工作的技巧? 或者有什么想法可以诊断错误吗?
我已经在配置中设置了不影响结果的用户 UDF 位置。
更新: 这是 lua 代码:
local function map_profile(record)
return map {interaction=record.interaction,
teamId=record.teamId, datetime=record.datetime,
timestamp=record.timestamp, version=record.version,
interactions=record.interactions}
end
function check_teamId(stream, teamId, startDate, endDate)
local function filter_teamId(record)
return record.teamId == teamId and
record.timestamp >= startDate and record.timestamp <= endDate
end
return stream : filter(filter_teamId) : map(map_profile)
end
您遇到 UDF 执行错误(代码:100)的最可能原因是 LUA 子系统的系统 and/or 用户路径设置不正确。如果您为客户端打开调试日志记录,您可能会看到以下一条或两条错误消息:
Apr 04 2016 08:15:19 UTC: DEBUG(45951) [conversions.cc:248] [config_from_jsobject] - Could not find a valid LUA system path ./aerospike-client-c/package/usr/local/aerospike/client/sys/udf/lua/
Apr 04 2016 08:15:19 UTC: DEBUG(45951) [conversions.cc:273] [config_from_jsobject] - Could not find valid LUA user path ./aerospike-client-c/package/usr/local/aerospike/client/usr/udf/lua
如果客户端无法自动确定正确的路径,则必须在配置中传递system/user路径。 (见下文。)
但是您在 Node.js 客户端中的 UDF 调用还有另一个问题。 UDF 的参数应该在 aggregationUDF
对象的 args
元素中传递,而不是在 arg
.
这是一个适合我的完整示例:
const Aerospike = require('aerospike')
const config = {
hosts: '192.168.33.10:3000',
log: { level: 5 },
modlua: {
userPath: './',
systemPath: './node_modules/aerospike/aerospike-client-c/lua/'
}
}
Aerospike.connect(config, (error, client) => {
if (error) throw error
var statement = {
aggregationUDF: {
module: 'agg',
funcname: 'check_teamId',
args: ['123', 0, 1456499994597]
}
}
var query = client.query('test', 'tracking', statement)
var stream = query.execute()
var count = 0
stream.on('error', (error) => console.error('error:', error))
stream.on('data', (result) => {
count++
console.log('result:', result)
})
stream.on('end', () => {
console.log('found %d records', count)
client.close()
})
})
请注意,此示例使用的 aerospike@2.0.0-alpha.1
客户端版本仅为 released。但是 UDF 查询的设置和执行与 v1.x 客户端相同。
我也把这个例子上传到Github here。此 Gist 还包含一个 setup.js
脚本,用于根据您的 map_profile
函数的预期创建一些示例记录。
欢迎在我们的 user forum 中跟进此事。我很想知道您是否将其用于您的应用程序。 (或有关 Aerospike Node.js 客户端的任何其他反馈!)