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



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

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

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

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

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

一旦你有了命名空间、set 和你的键,或者命名空间和记录摘要,你就可以从客户端 API 访问记录。 记录摘要是根据集合名称和密钥的组合计算RIPEMD160哈希。

Aerospike 中的记录是元组(元数据)。用Lua编写的Aerospike UDF,无论是记录UDF还是流UDF,都只能返回一种受支持的类型 - 字符串,整数,双精度,列表,映射,字节(请参阅:已知限制)。

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

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 的流筛选器转换为谓词筛选器表达式。它不适用于上面的示例,因为无法比较两个箱的值。但在大多数情况下,谓词表达式操作就足够了(请参阅 Java 客户端的 PredExp 类)。您根本不需要调用 UDF,它会运行得更快、扩展得更好,并且您不需要将记录转换为 bin 名称/值对的映射。

最新更新