Фильтр hbase для structrowkey byte [] ключ массива

HBase Фильтр по части ключа строки

Это моя таблица (Key is byte [] с использованием StructRowKeyBuilder с FixedLengthByteWritable для 'a', IntWritable для идентификатора и LongWritable для метки времени и содержит в основном всю информацию, значение является просто счетчиком) Ключ состоит из идентификатора (a или p), идентификатор переменной длины, дата со временем в секундах и пара других идентификаторов после этого (о чем меня действительно не волнует, так как я хочу фильтровать по времени).

KEY                             VALUE
a 13  2018-01-01T10:00:00 ...   1
a 13  2018-01-02T11:00:00 ...   1
a 13  2018-01-03T12:00:00 ...   1
a 13  2018-01-04T13:00:00 ...   1
a 15  2018-01-01T10:00:00 ...   1
a 15  2018-01-02T11:00:00 ...   1
a 15  2018-01-03T12:00:00 ...   1
a 123 2018-01-01T10:00:00 ...   1
a 123 2018-01-02T11:00:00 ...   1
a 123 2018-01-03T12:00:00 ...   1
a 123 2018-01-04T10:00:00 ...   1
...
p 13  2018-01-01T10:00:00 ...   1
p 13  2018-01-02T10:00:00 ...   1
p 13  2018-01-03T10:00:00 ...   1
p 666 2018-01-01T10:00:00 ...   1
...

Я хочу получить все данные за определенный период времени, скажем, между 2018-01-01T10: 00: 00 и 2018-01-02T12: 00: 00 для всех а.

Итак, я попробовал установить начальную и конечную строки сканирования.

StartRow    **a 0 2018-01-01T10:00:00** 
EndRow      **a Integer.MAX_VALUE 2018-01-02T:12:00:01 (+1 second to make it inclusive)**

Это не дало мне правильного результата, так как включало все, что находится между двумя клавишами. Так что записывай

КЛЮЧЕВАЯ ЦЕННОСТЬ а 13 2018-01-04T13: 00: 00 ... 1

также был включен. (Что имеет смысл)

Установка начальной строки на a 0 и конечной строки на целое число. MaxValue ограничивает количество возвращаемых строк только a.

Как мне отфильтровать эти строки на стороне сервера с помощью фильтров HBase? Поскольку ключи сериализованы в byte [], у меня нет четкого представления о том, как этого добиться с помощью фильтров.

Кто-нибудь, кто мог бы указать мне правильное направление? (или еще лучше предоставить пример кода на java)

Некоторый код (который, к сожалению, не работает так, как я хочу):

...
byte[] fromKey = Bytes.toBytes("a" + 0);
byte[] toKey = Bytes.toBytes("a" + Integer.MAX_VALUE);
Scan scan = new Scan(fromKey, toKey);

int minId = 0;
int maxId = Integer.MAX_VALUE;
final byte[] fromBytes = Bytes.toBytes("a" + minId + dateFromInMillis);
final BinaryPrefixComparator fromBinaryPrefixComparator = new BinaryPrefixComparator(fromBytes);
final Filter fromFilter = new RowFilter(CompareOp.GREATER_OR_EQUAL, fromBinaryPrefixComparator);

final byte[] toBytes = Bytes.toBytes("a" + maxId + dateFromInMillis);
final BinaryPrefixComparator toBinaryPrefixComparator = new BinaryPrefixComparator(toBytes);
final Filter toFilter = new RowFilter(CompareOp.LESS_OR_EQUAL, toBinaryPrefixComparator);

FilterList filterList= new FilterList(FilterList.Operator.MUST_PASS_ALL, fromFilter, toFilter);

scan.setFilter(filterList);
scanner = myTable.getScanner(scan);
...

Не могли бы вы добавить подробности о StructRowKeyBuilder, я думаю, это может быть причиной ваших результатов?

mbaxi 10.09.2018 14:23

Я не совсем уверен, как добавить детали для этого, поскольку кажется, что это что-то встроенное в protobuf / hbase. Тем временем я решил проблему, отправив несколько запросов и собрав данные. В основном - получить два списка идентификаторов (для префикса a и p), кэшировать их, а затем выполнить пару сканирований на основе <a | b> <id> dateFrom - dateTo и объединить результаты. Поскольку это просто время от времени используется и на самом деле не является производственным инструментом, а не для отладки и анализа.

El Shotodore 06.11.2018 16:08
2
2
112
1

Ответы 1

Я попытался эмулировать вашу проблему с помощью Phoenix, я не уверен, как StructRowKeyBuilder создает и сохраняет ключ, но если вы реализуете то же самое, используя ключ HBase с разделителями или используя композит Phoenix, вы сможете получить правильные результаты.

Вот что я сделал -

// Create table    
create table stackoverflow (
    id1 char(1) not null,
    id2 integer not null,
    eventdate Date not null,
    id3 varchar not null,
    id4 varchar not null,
    myvalue integer
    CONSTRAINT my_pk PRIMARY KEY (id1, id2, eventdate,id3, id4));

// add data
UPSERT INTO stackoverflow (id1, id2, eventdate,id3, id4, myvalue) VALUES('a', 13, '2018-01-01T10:00:00', 'dummy1', 'dummy2', 1);
.
.
.
UPSERT INTO stackoverflow (id1, id2, eventdate,id3, id4, myvalue) VALUES('p', 13, '2018-01-03T12:00:00', 'dummy1', 'dummy2', 1);
UPSERT INTO stackoverflow (id1, id2, eventdate,id3, id4, myvalue) VALUES('p', 666, '2018-01-01T10:00:00', 'dummy1', 'dummy2', 1);

Далее создан следующий запрос -

select  * from stackoverflow where id1='a' and id2 between 0 and 2147483647 and eventdate between TO_DATE('2018-01-01T10:00:00') and TO_DATE('2018-01-02T12:00:01');

Вот мои результаты, я могу добиться того же, используя HBase java API, но в моем случае сгенерированный составной ключ представляет собой объединенную строку, разделенную разделителем «0». Мне кажется, что StructRowKeyBuilder что-то меняет, потому что то, чего вы пытаетесь достичь, является очень нормальным сценарием использования.

a    13   2018-01-01 10:00:00.000  dummy1  dummy2  1        
a    13   2018-01-02 11:00:00.000  dummy1  dummy2  1        
a    15   2018-01-01 10:00:00.000  dummy1  dummy2  1        
a    15   2018-01-02 11:00:00.000  dummy1  dummy2  1        
a    123  2018-01-01 10:00:00.000  dummy1  dummy2  1        
a    123  2018-01-02 11:00:00.000  dummy1  dummy2  1        

Надеюсь это поможет.

Другие вопросы по теме