在单次扫描中使用MUST_PASS_ONE / ALL运算符组合两个FilterLists

时间:2018-02-22 12:39:11

标签: java hbase

考虑hbase shell scan 'table'结果:

ROW COLUMN+CELL
000 column=F:Q, timestamp=1519299345645, value=a
001 column=F:Q, timestamp=1519299345645, value=b
010 column=F:Q, timestamp=1519299345645, value=c
011 column=F:Q, timestamp=1519299345645, value=b
100 column=F:Q, timestamp=1519299345645, value=a
110 column=F:Q, timestamp=1519299345645, value=c
200 column=F:Q, timestamp=1519299345645, value=b
210 column=F:Q, timestamp=1519299345645, value=a

我想要的scan结果:

  • 行键以01
  • 开头
  • F:Q值为ab

上面的例子是:

ROW COLUMN+CELL
000 column=F:Q, timestamp=1519299345645, value=a
001 column=F:Q, timestamp=1519299345645, value=b
011 column=F:Q, timestamp=1519299345645, value=b
100 column=F:Q, timestamp=1519299345645, value=a

在hbase shell中,它会(忽略我提供的所有\s\n以提高可读性):

import org.apache.hadoop.hbase.filter.CompareFilter
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter
import org.apache.hadoop.hbase.util.Bytes

scan 'table' { 
  COLUMNS => 'F:Q', 
  FILTER => "
    (
      (PrefixFilter('0')) 
      OR 
      (PrefixFilter('1'))
    ) 
    AND 
    (
      SingleColumnValuFilter(
         Bytes.toBytes("F"),
         Bytes.toBytes("Q"),
         CompareFilter::CompareOp.valueOf('EQUAL'),
         Bytes.toBytes("a")
      )
      OR 
      SingleColumnValuFilter(
         Bytes.toBytes("F"),
         Bytes.toBytes("Q"),
         CompareFilter::CompareOp.valueOf('EQUAL'),
         Bytes.toBytes("b")
      )
    )
  "
}

因此,请考虑我在java中有两个过滤器列表:

List<Filter> prefixFilters            = new ArrayList<>();
List<Filter> singleColumnValueFilters = new ArrayList();

PrefixFilter one  = new PrefixFilter(Bytes.toBytes("1"));
PrefixFilter zero = new PrefixFilter(Bytes.toBytes("0"));

SingleColumnValueFilter a = new SingleColumnValueFilter(
    Bytes.toBytes("F"),
    Bytes.toBytes("Q"),
    CompareFilter.CompareOp.EQUAL,
    Bytes.toBytes("a") 
);

SingleColumnValueFilter b = new SingleColumnValueFilter(
    Bytes.toBytes("F"),
    Bytes.toBytes("Q"),
    CompareFilter.CompareOp.EQUAL,
    Bytes.toBytes("b") 
);

prefixFilters.add(zero);
prefixFilters.add(one);

singleColumnValueFilters.add(a);
singleColumnValueFilters.add(b);

FilterList prefixFiltersList = new FitlerList(FilterList.Operator.MUST_PASS_ONE, prefixFilters);
FilterList singleColumnValueFiltersList = new FitlerList(FilterList.Operator.MUST_PASS_ONE, singleColumnValueFilters);

问题:我如何将scan.setFilter()AND运算符组合在一起,就像我在shell中所做的那样?

<小时/> 我希望有一个特殊的FilterList构造函数,它可以接受逻辑比较器(AND / OR)和多个List<Filter>参数。由于没有,我被困住了。

1 个答案:

答案 0 :(得分:2)

最后,添加

FilterList filters = new FilterList(FilterList.Operator.MUST_PASS_ALL);
filters.addFilter(prefixFiltersList);
filters.addFilter(singleColumnValueFiltersList);

scan.setFilter(filters);

这可确保同时运行两个FilterLists,MUST_PASS_ALL充当AND条件。

为什么这样做?根据{{​​3}}:

  

由于您可以将过滤器列表用作过滤器列表的子项,因此您可以创建要评估的过滤器层次结构。