如何:在没有地图的情况下编写aerospike udf过滤器或在地图中返回完整记录

时间:2017-06-18 01:09:02

标签: filter lua udf aerospike

我在Aerospike中有一个带过滤器和地图的udf流。

如果我映射,根据我看到的所有示例,我可以从记录中选择字段并返回包含已过滤和选定字段的新地图。但是,我不想这样做。我想采取任何流,无论列/箱,应用过滤器并返回完整记录。一种方法可能是使用像stream:fiter(my_filter)这样的东西,而不是使用地图。直觉(至少对我来说)这只会过滤和转发流。对我来说,这似乎不起作用。我尝试的下一件事是使用地图,但只是传递完整的记录。这也不起作用。在这两种情况下,当我说它不起作用时,我得到一个空列表作为我的结果。

有人可以解释一下这应该如何运作。它让我绝对疯狂。 鉴于这是世界上最基本的东西之一,人们想用udfs,我意识到我错过了一些明显的东西。我应该指出,我用udfs做了很多复杂的事情,但由于某种原因,这对我来说是一个问题。

3 个答案:

答案 0 :(得分:2)

您缺少的是您无法在UDF返回值中返回记录或流类型。我相信所有返回类型都由aerospike系统lua模块映射到客户特定类型;它无法映射回记录“类型”。

如果您绝对想要获取记录,请将您的密钥存储在bin中,以地图类型或字符串类型或整数类型返回该bin - 这是您的应用程序最适合的类型。您还可以从地图类型的记录元数据中返回记录摘要。我没有通过UDF测试检索和返回记录摘要,但值得一试。

拥有命名空间后,设置和密钥,或命名空间&记录摘要,您可以从客户端API访问记录。记录摘要是根据集合名称和密钥的组合计算的RIPEMD160哈希值。

答案 1 :(得分:0)

我想我错过了什么。 我已经使用记录udfs更新记录和流udfs来做查询/ map reduce。问题是地图不似乎允许我选择所有列I.E.在不检查它们的情况下继续它们与等效的sql系统相比(我知道进行这种比较并不总是合理的);我想使用没有true map的udfs的过滤器部分。为什么?因为我没有其他方法来选择和过滤没有二级索引的集合,我想要多个过滤器。我该怎么做?

答案 2 :(得分:0)

Aerospike中的记录是元组(元数据 bins )。 Aerospike UDF written in Lua,无论是record UDF还是stream UDF,只能返回其中一种受支持的类型 - 字符串,整数,双精度,列表,地图,字节(请参阅:{ {3}})。

在流UDF中,如果您只有一个过滤器,则仍需要将记录的bin-name / bin-value对转换为map,并返回:

local function bins_match_filter(bin1, bin2)
  return function(rec)
    if rec[bin1] and rec[bin2] and
       (type(rec[bin1]) == type(rec[bin2])) and
       rec[bin1] == rec[bin2] then
      return true
    end
    return false
  end
end

local function record_to_map(rec)
  local ret = map()
  for i, bin_name in ipairs(record.bin_names(rec)) do
    ret[bin_name] = rec[bin_name]
  end
  return ret
end

function check_bins_match(stream, bin1, bin2)
  return stream : filter(bins_match_filter(bin1, bin2)) : map(record_to_map)
end

您可以将某些基于流UDF的过滤器转换为Known Limitations表达式。它不适用于上面的例子,因为没有办法比较两个箱子的值。但是对于大多数情况,谓词表达式操作是足够的(参见Java客户端的predicate filter类)。根本不需要调用UDF,运行速度更快,扩展性更好,并且您不需要将记录转换为bin名称/值对的映射。