Aerospike - 查询地图键

时间:2018-01-28 22:05:22

标签: nosql user-defined-functions aerospike

我对Aerospike DB有疑问。

我有一组学生,每个学生(记录键是StudentId),有一个<CourseId, Grade>的地图(bin)。 我正在尝试创建一些查询,而且我不确定这样做的正确方法是什么。

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

我想要创建的查询是:

  1. 对于每个学生,获取地图和列表中存在的所有courseIds。
  2. 对于每个学生,获取仅存在于其地图中而不在列表中的所有课程ID。
  3. 这里最好的方法是什么?我应该使用UDF吗?

    感谢。

1 个答案:

答案 0 :(得分:2)

这是record UDF有用的东西 - 扩展predicate filtering中尚未存在的功能。记录UDF可以将bin名称作为第一个参数,将list变量作为其第二个参数,并使用可选的第三个参数来确定这是否是“&#39; IN&#39;或者&#39; NOT IN&#39;然后根据课程ID地图迭代它。

您可以将此记录UDF应用于与包含学生的集合运行的扫描或查询匹配的每条记录。

<强> test.lua

class ADdUidToAppuserAndResponse < ActiveRecord::Migration

  disable_ddl_transaction!

  def change

    add_column :appusers, :archived, :boolean, algorithm: :concurrently, if !column_exists?(:appusers, :archived)
    add_column :responses, :archived, :boolean, algorithm: :concurrently, if !column_exists?(:responses, :archived)
    add_column :appuser_rewards, :archived, :boolean, algorithm: :concurrently, if !column_exists?(:appuser_rewards, :archived)

    add_column :appusers, :last_checked_campaigns_at, :datetime, algorithm: :concurrently, if !column_exists?(:appusers, :last_checked_campaigns_at)
    add_column :appusers, :last_checked_for_available_campaigns_at, :datetime, algorithm: :concurrently, if !column_exists?(:appusers, :last_checked_for_available_campaigns_at)    

    add_column :appusers, :uid, :uuid, default: 'uuid_generate_v4()', algorithm: :concurrently, if !column_exists?(:appusers, :uid)
    add_column :responses, :uid, :uuid, default: 'uuid_generate_v4()', algorithm: :concurrently, if !column_exists?(:responses, :uid)
    add_column :appuser_rewards, :uuid, :uuid, default: 'uuid_generate_v4()', algorithm: :concurrently, if !column_exists?(:appusers, :uuid)

    add_index :appusers, :uid, algorithm: :concurrently, where: "archived = false", if !index_exists?(:appusers, :uid)
    add_index :responses, :uid, algorithm: :concurrently, where: "archived = false", if !index_exists?(:responses, :uid)


  end
end

在AQL中:

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