Aerospike - 查询地图键

Aerospike - Query on Map Keys

我有一个关于 Aerospike DB 的问题。

我有一组学生,每个学生(记录键是StudentId),都有一个<CourseId, Grade>的映射(bin)。 我正在尝试创建一些查询,但不确定正确的方法是什么。

我有包含 <String> courseIds 列表的变量。

我要创建的查询是:

  1. 对于每个学生,获取地图和列表中存在的所有 courseId。
  2. 对于每个学生,获取所有只存在于他们的地图中而不存在于列表中的 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)