Как применить несколько QualifierFilter к строке в HBase
Мы хотели бы отфильтровать сканирование таблицы HBase с помощью двух QualifierFilters. Означает, что мы хотели бы получить только те строки таблицы, которые имеют определенный столбец "col_A" И (!) Определенный другой столбец "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);
...
ResultScanner не возвращает никаких результатов этого сканирования, хотя в таблице HBase есть несколько строк, в которых есть оба столбца: "col_A" и "col_B".
Если мы применяем только filter1 к проверке, все работает нормально, и мы получаем все строки, которые имеют 'col_A'. Если мы применяем только filter2 к сканированию, это то же самое. Мы получаем все строки, которые имеют 'col_B'.
Только если мы объединим эти два фильтра, мы не получим никаких результатов.
Что было бы правильным способом получить только те строки из таблицы, которые имеют col_A и col_B?
2 ответа
Вы можете добиться этого, определив следующие фильтры:
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
Я думаю, что эта линия является проблемой -
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
Вы хотите, чтобы это было -
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE);
Фильтр попытается найти столбец, у которого есть спецификатор столбца и такого столбца нет