arrays - StructRowKey byte[] 数组键上的 HBase 过滤器
问题描述
HBase 按行键的一部分过滤
这是我的表(键是 byte[],使用 StructRowKeyBuilder,FixedLengthByteWritable 表示“a”,IntWritable 表示 ID,LongWritable 表示时间戳,基本上包含所有信息,值只是一个计数器)或 p),一个可变长度的 id,一个以秒为单位的日期,以及之后的几个其他 id (我不太关心,因为我想过滤时间)。
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)**
这并没有给我正确的结果,因为它包含了两个键之间的所有内容。所以记录
关键值 a 13 2018-01-04T13:00:00 ... 1
也包括在内。(这是有道理的)
将开始行设置为a 0
整数,结束行设置为整数。MaxValue
将返回的行数限制为仅a
s。
我将如何使用 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);
...
解决方案
我尝试使用 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
希望这可以帮助。
推荐阅读
- dask - Dask 与 Pyarrow 的兼容性并从 CSV 读取
- vue.js - Vue2/Router3 — 滚动行为不起作用
- drag-and-drop - Kotlin可组合detectDragGestures在放置位置输出?
- elasticsearch - 我们如何在 Java 代码中实现累积基数?
- javascript - 如果我单击按钮,有没有办法查看按高度计算的手风琴菜单?
- excel - 如何遍历范围对象VBA的每一行中的特定列?
- c# - 在 Unity c# 中,我无法使用 animation.SetInteger 让动画过渡
- reactjs - 如何修复 npm 漏洞?我尝试了两种方法,问题仍然存在
- publish-subscribe - 当 IoT Core shadow 的属性被删除(设置为 null)时,客户端应该订阅哪个主题?
- c# - 在 Autofac 中,当我两次调用相同类型的 RegisterInstance 时,如何获取特定的一个实例?