如何将几个QualifierFilter应用于HBase中的一行

时间:2012-11-14 13:02:53

标签: filter hbase database-scan

我们希望使用两个QualifierFilters过滤HBase表上的扫描。 意味着我们只希望获得表格的行,这些行具有某个列'col_A' AND (!)某个其他列'col_B'。

我们目前的方法如下:

FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
Filter filter1 = new QualifierFilter(CompareOp.EQUAL, new BinaryComparator("col_A".getBytes()));
filterList.addFilter(filter1);
Filter filter2 = new QualifierFilter(CompareOp.EQUAL, new BinaryComparator("col_B".getBytes()));
filterList.addFilter(filter2);

Scan scan = new Scan();
scan.setFilter(filterList);
... 

虽然HBase表中有多行同时包含“col_A”和“col_B”列,但ResultScanner不会从此扫描返回任何结果。

如果我们只将scan1应用于扫描,一切正常,我们会得到所有'col_A'的行。 如果我们只将filter2应用于扫描,则它是相同的。我们确实获得了所有包含'col_B'的行。

只有当我们合并这两个过滤器时,我们才会得到任何结果。

只从表中获得col_A AND col_B的行的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

您可以通过定义以下过滤器来实现此目的:

List<Filter> filters = new ArrayList<Filter>(2);
byte[] colfam = Bytes.toBytes("c");
byte[] fakeValue = Bytes.toBytes("DOESNOTEXIST");
byte[] colA = Bytes.toBytes("col_A");
byte[] colB = Bytes.toBytes("col_B");

SingleColumnValueFilter filter1 = 
    new SingleColumnValueFilter(colfam, colA , CompareOp.NOT_EQUAL, fakeValue);  
filter1.setFilterIfMissing(true);
filters.add(filter1);

SingleColumnValueFilter filter2 = 
    new SingleColumnValueFilter(colfam, colB, CompareOp.NOT_EQUAL, fakeValue);          
filter2.setFilterIfMissing(true);
filters.add(filter2);

FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, filters);
Scan scan = new Scan();
scan.setFilter(filterList);

这里的想法是为您要查找的每列定义一个SingleColumnValueFilter,每个列都有一个假值和一个CompareOp.NOT_EQUAL运算符。即: 这样的SingleColumnValueFilter将返回给定名称的所有列。

来源:http://mapredit.blogspot.com/2012/05/using-filters-in-hbase-to-match-two.html

答案 1 :(得分:3)

我认为这一行是问题 -

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

你希望它是 -

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

过滤器将尝试查找同时具有列限定符且没有此列

的列