【问题标题】:Aerospike udf lua stream skip filter if condition met如果满足条件,则 Aerospike udf lua 流跳过过滤器
【发布时间】:2017-02-13 14:25:51
【问题描述】:

情况:

我在 aerospike 中有复杂的垃圾箱,例如: object_id,status,create_time,end_at_time,status_client,assigned_to_id,created_by_id,is_s_provider,is_s_client,start_at_time,_id,end_time

而且我需要对任何 bins 字段进行聚合。 在 sql 格式中,它应该类似于:

select count(*) from table where status=13 and where is_s_provider=True;

经过一些研究,我制作了如下所示的 lua 模块:

function count(stream,created_by,status,status_client,obj,client,provider,assigned_to,create_time,end_time,start_at_time,end_at_time)                                                                                                                                                                                  
    local created_by_f = created_by_filter(created_by)                                                                                                                                                                                                                              
    local status_f = status_filter(status)                                                                                                                                                                                                                                          
    local status_client_f = status_client_filter(status_client)                                                                                                                                                                                                                      
    local obj_f = ojb_filter(obj)                                                                                                                                                                                                                                                   
    local client_f = client_filter(client)                                                                                                                                                                                                                                          
    local provider_f = provider_filter(provider)                                                                                                                                                                                                                                    
    local assigned_to_f = assigned_to_filter(assigned_to)
    local create_time_f= create_time_filter(create_time)
    local end_time_f = end_time_filter(end_time)                                                                                                                                                                                                                           
    local start_at_time_f = start_at_time_filter(start_at_time)
    local end_at_time_f = end_at_time_filter(end_at_time)

    function mapper(rec)                                                                                                                                                                                                                                                            
            return 1                                                                                                                                                                                                                                                                
    end                                                                                                                                                                                                                                                                             
    local function reducer(v1, v2)
        return v1 + v2
    end
    return stream : filter(created_by_f): filter(status_f): filter(status_client_f) : filter(obj_f): filter(client_f): filter(provider_f): filter(assigned_to_f): filter(create_time_f):filter(end_time_f): filter(start_at_time_f): filter(end_at_time_f): map(mapper) : reduce(reducer)
end

结束过滤器(我有 11 个)看起来像:

....
local function status_client_filter(status_client)
    local key = string.sub(status_client, 1, 1)                                                                                                                                                                                                                                       
    local data = string.sub(status_client,2)  
    return function(record)
        if status_client == '*' then
            return true
        elseif key == '!' then  
            if record['status_client'] ~= tonumber(data) then
                return true
            else
                return false
            end
        elseif key == '=' then
            if record['status_client'] == tonumber(data) then
                return true
            else
                return false
            end
        else
            return false
        end
    end
end
....

索引已创建并在 aql 中检查它是否有效我运行:

aql> aggregate count.count('*','*','=13','*','*','*','*','*','*','*','*') on test.demo 
+-------+
| count |
+-------+
| 895   |
+-------+
1 row in set (0.219 secs)

aql> 

一切正常,我得到了我想要的,除了一个大问题,0.219 秒很多。

问题:

如果满足条件,有什么方法可以跳过过滤器,例如,如果我传递给过滤器函数 status_client_filter('*') 那么流过滤器函数不应该遍历所有记录,而是将它们传递给之前来自流函数的记录.它应该会大大提高性能。 还是动态过滤的另一种方法?还是另一种复杂聚合的架构?

【问题讨论】:

    标签: lua aggregation udf aerospike


    【解决方案1】:

    您的应用程序可以在这里提供帮助。过滤阶段不是强制性的。因此,您可以在没有过滤器阶段的情况下拥有一个更高级别的 lua 函数。您的应用程序可以检测过滤器是否为 * 并调用无过滤器的 lua 函数。此外,如果根本没有where 子句,那么使用基于扫描的聚合比使用基于二级索引的聚合要好。扫描比二级索引查询快得多。

    【讨论】:

      【解决方案2】:

      从 release 3.12 开始,您将在使用 predicate filtering 调用 UDF 之前进行过滤。这目前在Java、C、C#Go 等的客户端中可用。

      这将允许依赖于谓词表达式完成的预过滤的更轻、更快的 UDF。

      【讨论】:

        猜你喜欢
        • 2017-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多