如何通过部分行键过滤HBase的扫描?
How filter Scan of HBase by part of row key?
我有带行键的 HBase table,行键由文本 ID 和时间戳组成,如下所示:
...
string_id1.1470913344067
string_id1.1470913345067
string_id2.1470913344067
string_id2.1470913345067
...
我如何过滤 HBase 的扫描(在 Scala 或 Java 中)以获得具有大于某个值的字符串 ID 和时间戳的结果?
谢谢
假设你以某种方式最终将你的行置于一个单子可遍历结构中,如 List 或 RDD。现在,您只想拥有 id = "string_id2"
和 timestamp > 1470913345000
.
的字符串
现在这里的问题是什么?只需根据这两个标准过滤可遍历的单子结构。
val filtered = listOrRddOfLines
.map(l => {
val idStr :: timestampStr :: Nil = l.split('.').toList
(idStr, timestampStr.toLong)
})
.filter({
case (idStr, timestamp) => idStr.equals("string_id2") && (timestamp > "1470913345000".toLong)
})
我通过使用过滤器解决了我的问题:
- PrefixFilter
(我将行键的第一部分放入此过滤器。在我的例子中 - 字符串 ID,例如 "string_id1.")
- RowFilter
(我在那里放了两个参数:第一个 - CompareOp.GREATER_OR_EQUAL
,第二个 - 我所有的行键和必要的时间戳,例如 "string_id1.1470913345000"
结果我得到了所有带有行键的单元格,如果第一部分有必要 string_id
,并且时间戳大于或等于我在第二部分中放入过滤器的时间戳。这正是我想要的。
代码片段:
val s = new Scan()
s.addFamily(family.getBytes)
val filterList = new FilterList()
filterList.addFilter(new PrefixFilter(Bytes.toBytes(prefixOfRowKey)))
filterList.addFilter(new RowFilter(CompareOp.GREATER_OR_EQUAL, new BinaryComparator(valueForBinaryFilter.getBytes())))
s.setFilter(filterList)
val scanner = table.getScanner(s)
感谢所有帮助找到解决方案的人。
模糊行方法对于这种需求和数据量很大时是有效的:
正如这个 article 所解释的
FuzzyRowFilter 将行键和掩码信息作为参数。
在上面的示例中,如果我们想要查找最后登录的用户并且行键格式为 userId_actionId_timestamp
(其中 userId
具有固定长度,例如 4 个字符),我们的模糊行键正在寻找的是 ????_login_
。这转化为 FuzzyRowKey 的以下参数:
FuzzyRowFilter rowFilter = new FuzzyRowFilter(
Arrays.asList(
new Pair<byte[], byte[]>(
Bytes.toBytesBinary("\x00\x00\x00\x00_login_"),
new byte[] {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0})));
建议阅读 hbase-the-definitive 指南 -->Client API: Advanced Features
我有带行键的 HBase table,行键由文本 ID 和时间戳组成,如下所示:
...
string_id1.1470913344067
string_id1.1470913345067
string_id2.1470913344067
string_id2.1470913345067
...
我如何过滤 HBase 的扫描(在 Scala 或 Java 中)以获得具有大于某个值的字符串 ID 和时间戳的结果?
谢谢
假设你以某种方式最终将你的行置于一个单子可遍历结构中,如 List 或 RDD。现在,您只想拥有 id = "string_id2"
和 timestamp > 1470913345000
.
现在这里的问题是什么?只需根据这两个标准过滤可遍历的单子结构。
val filtered = listOrRddOfLines
.map(l => {
val idStr :: timestampStr :: Nil = l.split('.').toList
(idStr, timestampStr.toLong)
})
.filter({
case (idStr, timestamp) => idStr.equals("string_id2") && (timestamp > "1470913345000".toLong)
})
我通过使用过滤器解决了我的问题:
- PrefixFilter
(我将行键的第一部分放入此过滤器。在我的例子中 - 字符串 ID,例如 "string_id1.")
- RowFilter
(我在那里放了两个参数:第一个 - CompareOp.GREATER_OR_EQUAL
,第二个 - 我所有的行键和必要的时间戳,例如 "string_id1.1470913345000"
结果我得到了所有带有行键的单元格,如果第一部分有必要 string_id
,并且时间戳大于或等于我在第二部分中放入过滤器的时间戳。这正是我想要的。
代码片段:
val s = new Scan()
s.addFamily(family.getBytes)
val filterList = new FilterList()
filterList.addFilter(new PrefixFilter(Bytes.toBytes(prefixOfRowKey)))
filterList.addFilter(new RowFilter(CompareOp.GREATER_OR_EQUAL, new BinaryComparator(valueForBinaryFilter.getBytes())))
s.setFilter(filterList)
val scanner = table.getScanner(s)
感谢所有帮助找到解决方案的人。
模糊行方法对于这种需求和数据量很大时是有效的: 正如这个 article 所解释的 FuzzyRowFilter 将行键和掩码信息作为参数。
在上面的示例中,如果我们想要查找最后登录的用户并且行键格式为 userId_actionId_timestamp
(其中 userId
具有固定长度,例如 4 个字符),我们的模糊行键正在寻找的是 ????_login_
。这转化为 FuzzyRowKey 的以下参数:
FuzzyRowFilter rowFilter = new FuzzyRowFilter(
Arrays.asList(
new Pair<byte[], byte[]>(
Bytes.toBytesBinary("\x00\x00\x00\x00_login_"),
new byte[] {1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0})));
建议阅读 hbase-the-definitive 指南 -->Client API: Advanced Features