파이문

[HBase] FilterList 에서 OR 조건 사용하기 본문

TIL

[HBase] FilterList 에서 OR 조건 사용하기

민Z 2021. 2. 22. 21:00

동일한 Column Qualifier 에서 (이를 'A' 라고 하겠다.)  조건 여러개를 OR 로 필터 하고 싶었다.

 

예시로 보자면 A 가 1 인 경우 또는 2인 경우를 스캔하고 싶어, 다음과 같이 작성하였다. (실제로는 Byte 값이 들어간다.)

Scan scan = new Scan();
FilterList filterList = new FilterList();
SingleColumnValueFilter aIsOne = new SingleColumnValueFilter(
        'CF',
        'A',
        CompareFilter.CompareOp.EQUAL,
        1
);

SingleColumnValueFilter aIsTwo = new SingleColumnValueFilter(
        'CF',
        'A',
        CompareFilter.CompareOp.EQUAL,
        2
);


filterList.addFilter(aIsOne);
filterList.addFilter(aIsTwo);

scan.setFilter(filterList);

// 생략

 

그런데 처음엔 잘 동작하다가, 어느 순간 Scan timeout 이 났다.

 

알고보니 FilterList 기본 Operator 는 MUST_PASS_ALL 이었고, 처음엔 aIsOne 에 해당하는 필터가 적용 되어 동작하였고

이후 더 이상 aIsOne 에 해당되는 데이터가 없어 이를 찾느라 Scan timeout 이 났던 것이다.

 

AND 조건이 아닌 OR 조건이기 때문에 FilterList operator 값을 수정해야 했다.

FilterList Operator

FilterList 의 Operator 종류는 다음 두 가지이다.

  • MUST_PASS_ALL 모든 필터를 통과한 값만 결과에 추가한다. 
  • MUST_PASS_ONE 필터 중에서 하나라도 통과한 값은 모두 결과 값에 추가한다.

두 가지 필터 중 하나라도 해당하는 경우 (OR 조건) 에는 MUST_PASS_ONE 을 사용하여야 한다.

 

사용 방법은 아래 처럼 operator 값을 초기 설정하면 된다.

FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE);

다른 조건 (filter) 와 같이 사용하고 싶다면?

Column Qualifier 'A' 가 (1 또는 2) 그리고 Column Qualifier 'B' 가 0인 것만 가져오고 싶다고 해보자.  이럴 경우 'B' 는 A 조건과 상관 없이 0 이어야 하는 것이기 때문에 위에서 정의한 filterList 에 추가하면 안된다.

 

위에서 정의한 (MUST_PASS_ONE 을 operator 로 갖는) FilterList를 사용하게 되면 A 는 1 이거나, A 는 2 이거나, B 는 0 이거나 와 같은 조건식이 된다.

 

이 경우 OR 조건 따로, AND 조건 따로 이기 때문에 FilterList 를 여러개 두면 원하는 조건식을 만들 수 있다.

 

(A == 1 OR A == 2) AND B == 0 를 표현하는 예시는 다음과 같다.

// 전체 필터를 넣을 filterList
FilterList allFilters = new FilterList();

// A 만을 위한 filter
FilterList aCompareFilter = new FilterList(FilterList.Operator.MUST_PASS_ONE);

// A 의 OR 조건을 추가
aCompareFilter.addFilter(/* A 가 1인 경우*/);
aCompareFilter.addFilter(/* A 가 2인 경우*/);

// A 조건 추가
allFilters.addFilter(aCompareFilter);

// B 조건 정의
SingleColumnValueFilter bIsZero = new SingleColumnValueFilter(
        'CF',
        'B',
        CompareFilter.CompareOp.EQUAL,
        0
);
// B 조건 추가
allFilters.addFilter(bIsZero);

// 필터 적용
scan.setFilters(allFilters);

이렇게 filterList(allFilters) 안에 filterList(aCompareFilter) 를 또 넣을 수 있는 이유는, FilterList가 Filter 라는 클래스를 상속 받았고 addFilter 에서 인자 값으로 Filter 객체를 받기 때문이다. (filterList 메서드 중에는 List<Filter> 를 받는 addFilter 도 있다. 3.0.0 기준 client-api 임)

 

filterList 는 List 가 아니라 Filter 라는 클래스의 하위 클래스이다.

 

Filter 조건을 다양하게, 여러개 쓰고 싶다면 FilterList 를 위와 같이 사용하면 된다.

 

참고

- hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/FilterList.Operator.html

- hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/FilterList.html

 

'TIL' 카테고리의 다른 글

github action 알아보기 (docker 예시 포함)  (0) 2022.06.17
도커 컨테이너 로그 삭제  (0) 2021.02.18
gradle-ssh-plugin 사용하기  (0) 2021.02.18
gradle proxy 설정  (0) 2021.02.17
git rm 한 file 복구(reset, restore) 하기  (0) 2021.02.16
Comments