2016-10-05 11 views
0

상황 :Aerospike UDF의 루아 스트림 필터를 건너

내가 aerospike 복잡한 쓰레기통이 같은 : OBJECT_ID, 상태, 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

그리고 모든 빈 입력란에서 집계를 수행해야합니다. 보이는 내가 만든 몇 가지 조사 루아 모듈 후

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

:이처럼 보일 것이다 SQL 형식에서

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 

최종 필터 (I 그들 중 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를 필터링 통과하면

필터를 건너 뛸 수있는 방법은 예를 들어,이 전에는 스트림 함수에서 온 것처럼. 성능이 많이 향상됩니다. 동적 필터링을하는 또 다른 방법은 무엇입니까? 또는 복잡한 집계를위한 다른 아키텍처?

답변

0

신청서가 도움이 될 수 있습니다. 필터 단계는 필수는 아닙니다. 따라서 필터 단계가 없으면 하나의 고급 루아 함수를 가질 수 있습니다. 필터가 *인지 여부를 응용 프로그램이 감지하고 필터없는 lua 함수를 호출 할 수 있습니다. 또한 where 절이 전혀없는 경우 보조 색인보다 하나의 검사 기반 집계를 사용하는 것이 좋습니다. 스캔은 보조 인덱스 쿼리보다 훨씬 빠릅니다.

0

release 3.12부터 predicate filtering을 사용하여 UDF를 호출하기 전에 필터링을 수행합니다. 현재 클라이언트에서 Java, C, C#Go 등으로 사용할 수 있습니다.

이렇게하면 술어 표현식에 의한 사전 필터링에 의존하는 더욱 가볍고 빠른 UDF를 사용할 수 있습니다.