AQL 来自流 UDF 的不同结果取决于输出样式(table、json)
AQL different results from stream UDF depending on output style (table, json)
我正在尝试使用 UDF 创建聚合 (map | reduce),但一开始就出错了。在 Aerospike 中,我有一个包含 bin 'u'(二级索引)和 bin 'v' 的集合,它是一个对象列表(带有交易列表和其他拍卖数据的拍卖),我有一个流 UDF 来聚合内部结构的 'v':
function trans_sum_by_years(s)
local function transform(rec)
local l = map()
local x = map()
local trans, auctions = 0, 0
for i in list.iterator(rec['v'] or list()) do
auctions = auctions + 1
for t in list.iterator(i['t'] or list()) do
trans = trans + 1
date = os.date("*t", t['ts'])
if l[date['year']] ~= nil then
l[date['year']] = l[date['year']] + t['price'] * t['qty']
else
l[date['year']] = t['price'] * t['qty']
end
end
end
x.auctions = auctions
x.trans = trans
x.v = l
return x
end
return s : map(transform)
end
问题是根据 table 或 json 上的设置输出,输出非常不同。在第一种情况下似乎一切正常:
{"trans":594, "auctions":15, "v":{2010:1131030}}
{"trans":468, "auctions":68, "v":{2011:1472976, 2012:5188}}
......
第二次我从内部记录聚合中得到空对象。
{
"trans_sum_b...":{
"trans": 389,
"auctions": 89,
"v":{}
}
},
{
"trans_sum_b...":{
"trans": 542,
"auctions": 30,
"v":{}
}
}
.....
我更喜欢 json 输出并且浪费了几个小时来找出为什么我得到空 'v' 字段但没有成功。所以我的问题是 "what the hell is going on" ;-) 如果我的代码是正确的,那么 json 输出有什么问题,我看不到结果。如果我的代码错了,为什么错了,为什么 table 输出的结果是我需要的。
@user1875438 您的代码是正确的。好像是aql有bug
我的结果和你的一样,使用json模式时v的字段为空。
当运行这两个命令时,我用tcpdump
抓取了aerospike-server的响应,发现响应是一样的,所以我认为很可能是aql工具有bug。
159 0x0050: 0001 0000 0027 0113 0007 5355 4343 4553 .....'....SUCCES
160 0x0060: 5383 a603 7472 616e 7301 a903 6175 6374 S...trans...auct
161 0x0070: 696f 6e73 01a2 0376 81cd 07ce 01 ions...v.....
162 01:57:38.255065 IP localhost.hbci > localhost.57731: Flags [P.], seq 98:128, ack 144, win 42853, options [nop,nop,TS val 976630236 ecr 976630223], length 30
163 0x0000: 4500 0052 55f8 4000 4006 0000 7f00 0001 E..RU.@.@.......
我刚刚发布了一个问题 here。
答案非常简单。但我是 Aerospike/Lua 的新手,我不相信自己的知识,所以我到处搜索错误,但在 AQL/UDF 区域内。这个问题更根本,会干扰 JSON 本身的规范。
JSON 中的键必须是字符串!所以tostring(date['year'])
解决了问题。
另一个问题是它是错误还是功能:-) 如果 Aerospike 的地图类型允许整数键,是否应该有从整数到字符串的自动键转换以满足 JSON 规范?恕我直言,应该有,但可能有些人不同意地图类型不适用于整数键...
我正在尝试使用 UDF 创建聚合 (map | reduce),但一开始就出错了。在 Aerospike 中,我有一个包含 bin 'u'(二级索引)和 bin 'v' 的集合,它是一个对象列表(带有交易列表和其他拍卖数据的拍卖),我有一个流 UDF 来聚合内部结构的 'v':
function trans_sum_by_years(s)
local function transform(rec)
local l = map()
local x = map()
local trans, auctions = 0, 0
for i in list.iterator(rec['v'] or list()) do
auctions = auctions + 1
for t in list.iterator(i['t'] or list()) do
trans = trans + 1
date = os.date("*t", t['ts'])
if l[date['year']] ~= nil then
l[date['year']] = l[date['year']] + t['price'] * t['qty']
else
l[date['year']] = t['price'] * t['qty']
end
end
end
x.auctions = auctions
x.trans = trans
x.v = l
return x
end
return s : map(transform)
end
问题是根据 table 或 json 上的设置输出,输出非常不同。在第一种情况下似乎一切正常:
{"trans":594, "auctions":15, "v":{2010:1131030}}
{"trans":468, "auctions":68, "v":{2011:1472976, 2012:5188}}
......
第二次我从内部记录聚合中得到空对象。 { "trans_sum_b...":{ "trans": 389, "auctions": 89, "v":{} } }, { "trans_sum_b...":{ "trans": 542, "auctions": 30, "v":{} } } .....
我更喜欢 json 输出并且浪费了几个小时来找出为什么我得到空 'v' 字段但没有成功。所以我的问题是 "what the hell is going on" ;-) 如果我的代码是正确的,那么 json 输出有什么问题,我看不到结果。如果我的代码错了,为什么错了,为什么 table 输出的结果是我需要的。
@user1875438 您的代码是正确的。好像是aql有bug
我的结果和你的一样,使用json模式时v的字段为空。
当运行这两个命令时,我用tcpdump
抓取了aerospike-server的响应,发现响应是一样的,所以我认为很可能是aql工具有bug。
159 0x0050: 0001 0000 0027 0113 0007 5355 4343 4553 .....'....SUCCES
160 0x0060: 5383 a603 7472 616e 7301 a903 6175 6374 S...trans...auct
161 0x0070: 696f 6e73 01a2 0376 81cd 07ce 01 ions...v.....
162 01:57:38.255065 IP localhost.hbci > localhost.57731: Flags [P.], seq 98:128, ack 144, win 42853, options [nop,nop,TS val 976630236 ecr 976630223], length 30
163 0x0000: 4500 0052 55f8 4000 4006 0000 7f00 0001 E..RU.@.@.......
我刚刚发布了一个问题 here。
答案非常简单。但我是 Aerospike/Lua 的新手,我不相信自己的知识,所以我到处搜索错误,但在 AQL/UDF 区域内。这个问题更根本,会干扰 JSON 本身的规范。
JSON 中的键必须是字符串!所以tostring(date['year'])
解决了问题。
另一个问题是它是错误还是功能:-) 如果 Aerospike 的地图类型允许整数键,是否应该有从整数到字符串的自动键转换以满足 JSON 规范?恕我直言,应该有,但可能有些人不同意地图类型不适用于整数键...