For this example I am setting up a record with two bins (a
, b
), each containing a map similar to the one you’ve shown. Only one of the fields exists in both (KPI613
):
aql> select * from test.demo where PK ='1'
+------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
| a | b |
+------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
| {"KPI613":{"RT1167":1, "CH1010280":10, "CH1024141":100}, "KPI608":{"RT1167":2, "CH1010280":20, "CH1024141":200}} | {"KPI613":{"RT1167":4, "CH1010280":40, "CH1024141":400}, "KPI715":{"RT1167":8, "CH1010280":80, "CH1024141":800}} |
+------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------+
I created a record UDF module called go.lua
function try(rec)
local a = rec['a']
local b = rec['b']
return map.merge(a, b, function (v1, v2)
if (type(v1) == "number" and type(v2) == "number") then
return v1 + v2
elseif (getmetatable(v1) == getmetatable(map()) and
getmetatable(v2) == getmetatable(v1)) then
return map.merge(v1, v2, function (n1, n2)
debug("%d + %d = %d", n1, n2, (n1+n2))
return n1 + n2
end)
end
end)
end
Then I called it from a simple Python script:
from __future__ import print_function
import aerospike
config = {'hosts': [('192.168.119.3',3000)]}
client = aerospike.client(config).connect()
res = client.apply(('test', 'demo', '1'), 'go', 'try', [])
print(res)
client.close()
The result is as expected:
{'KPI608': {'CH1010280': 20, 'CH1024141': 200, 'RT1167': 2}, 'KPI715': {'CH1010280': 80, 'CH1024141': 800, 'RT1167': 8}, 'KPI613': {'CH1010280': 50, 'CH1024141': 500, 'RT1167': 5}}
As you can see, you need to think about the types, because Aerospike is schema-free, and map.merge()
handles merging two maps with similarly named fields of the type number
by default. If you want to handle other types you’ll need to provide your own function. You know your data, so it’s up to you to write the appropriate code.
In my example I’m only checking for numeric (integer
) and Map
types. If your data is messy you’ll need to also check for, and handle string
, list
, etc.