Aerospike - 查询地图键
Aerospike - Query on Map Keys
我有一个关于 Aerospike DB 的问题。
我有一组学生,每个学生(记录键是StudentId),都有一个<CourseId, Grade>
的映射(bin)。
我正在尝试创建一些查询,但不确定正确的方法是什么。
我有包含 <String>
courseIds 列表的变量。
我要创建的查询是:
- 对于每个学生,获取地图和列表中存在的所有 courseId。
- 对于每个学生,获取所有只存在于他们的地图中而不存在于列表中的 courseId。
最好的方法是什么?我应该使用 UDF 吗?
谢谢。
这是一种record UDF is good for - extending functionality that doesn't yet exist in predicate filtering的东西。记录 UDF 可以将 bin 名称作为第一个参数,您的列表变量作为其第二个参数,以及一个可选的第三个参数来决定这是 'IN' 还是 'NOT IN',然后根据课程 ID 地图。
您可以将此记录 UDF 应用于扫描或查询匹配的每条记录 运行 针对包含学生的集合。
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
在 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)
我有一个关于 Aerospike DB 的问题。
我有一组学生,每个学生(记录键是StudentId),都有一个<CourseId, Grade>
的映射(bin)。
我正在尝试创建一些查询,但不确定正确的方法是什么。
我有包含 <String>
courseIds 列表的变量。
我要创建的查询是:
- 对于每个学生,获取地图和列表中存在的所有 courseId。
- 对于每个学生,获取所有只存在于他们的地图中而不存在于列表中的 courseId。
最好的方法是什么?我应该使用 UDF 吗?
谢谢。
这是一种record UDF is good for - extending functionality that doesn't yet exist in predicate filtering的东西。记录 UDF 可以将 bin 名称作为第一个参数,您的列表变量作为其第二个参数,以及一个可选的第三个参数来决定这是 'IN' 还是 'NOT IN',然后根据课程 ID 地图。
您可以将此记录 UDF 应用于扫描或查询匹配的每条记录 运行 针对包含学生的集合。
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
在 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)