I have a question about Aerospike DB.
I have set of students, and each student (record key is StudentId), has a map (bin) of <CourseId, Grade>
.
I'm trying to create some queries, and I'm not sure what is the correct way to do it.
I have variable containing a List of <String>
courseIds.
The queries that I want to create are:
What is the best approach here? Should I use UDF?
Thanks.
This is the kind of thing a record UDF is good for - extending functionality that doesn't yet exist in predicate filtering. The record UDF can take the bin name as the first argument, your list variable as its second argument, and an optional third argument for deciding whether this is an 'IN' or 'NOT IN', then iterate through it against the map of course IDs.
You can apply this record UDF to every record matched by a scan or query running against the set containing the students.
test.lua
function list_compare(rec, bin, l, not_in_l)
if rec[bin] then
local b = rec[bin]
if (tostring(getmetatable(rec[bin])) == tostring(getmetatable(list()))) then
iter = list.iterator
elseif (tostring(getmetatable(rec[bin])) == tostring(getmetatable(map()))) then
iter = map.values
else
return nil
end
local s = {}
local l_keys = {}
if (not_in_l ~= nil) then
for v in list.iterator(l) do
l_keys[v] = 1
end
end
for i in list.iterator(l) do
for v in iter(b) do
if (not_in_l == nil) then
if (i == v) then
s[v] = 1
end
else
if (i ~= v and not l_keys[v]) then
s[v] = 1
end
end
end
end
local keys = {}
for k,v in pairs(s) do
table.insert(keys, k)
end
table.sort(keys)
return list(keys)
end
end
In AQL:
$ aql
Aerospike Query Client
Version 3.15.1.2
C Client Version 4.3.0
Copyright 2012-2017 Aerospike. All rights reserved.
aql> register module './test.lua'
OK, 1 module added.
aql> insert into test.demo (PK,i,s,m,l) values ('88',6,'six',MAP('{"a":2, "b":4, "c":8, "d":16}'),LIST('[2, 4, 8, 16, 32, 128, 256]'))
OK, 1 record affected.
aql> select * from test.demo where PK='88'
+---+-------+--------------------------------------+-------------------------------------+
| i | s | m | l |
+---+-------+--------------------------------------+-------------------------------------+
| 6 | "six" | MAP('{"a":2, "b":4, "c":8, "d":16}') | LIST('[2, 4, 8, 16, 32, 128, 256]') |
+---+-------+--------------------------------------+-------------------------------------+
1 row in set (0.001 secs)
aql> execute test.list_compare("l", LIST('[1,2,3,4]')) on test.demo where PK='88'
+----------------+
| list_compare |
+----------------+
| LIST('[2, 4]') |
+----------------+
1 row in set (0.002 secs)
aql> execute test.list_compare("l", LIST('[1,2,3,4]'),1) on test.demo where PK='88'
+-------------------------------+
| list_compare |
+-------------------------------+
| LIST('[8, 16, 32, 128, 256]') |
+-------------------------------+
1 row in set (0.001 secs)
aql> execute test.list_compare("m", LIST('[1,2,3,4]')) on test.demo where PK='88'
+----------------+
| list_compare |
+----------------+
| LIST('[2, 4]') |
+----------------+
1 row in set (0.001 secs)
aql> execute test.list_compare("m", LIST('[1,2,3,4]'), 1) on test.demo where PK='88'
+-----------------+
| list_compare |
+-----------------+
| LIST('[8, 16]') |
+-----------------+
1 row in set (0.000 secs)