行范围过滤器与子字符串比较器 - Hbase
Row Range Filter vs Substring comparator - Hbase
我的 Hbase rowkeys
是这样设置的:timestamp-userid
我需要扫描 hbase 中的所有行和 return 任何 userid = 38356644322545651
所以我们有
vid = "38356644322545651";
目前我正在使用一个小技巧,一个子字符串比较器:
Scan s = new Scan();
Filter f = new RowFilter(CompareOp.EQUAL, new SubstringComparator(vid));
s.setFilter(f);
这很完美!
但是,我质疑检查子字符串是否存在的效率。
此外,如果将来还有其他 rowkeys
包含上述 rowkey
可能会导致问题。
所以我找到了一个叫做 MultiRowRangeFilter
的东西。
看起来很简单。我的实现如下:
Scan s = new Scan();
List<MultiRowRangeFilter.RowRange> lst = new ArrayList<MultiRowRangeFilter.RowRange>();
lst.add(new MultiRowRangeFilter.RowRange("0-" + vid, true, "z-" + vid, true));
s.setFilter(new MultiRowRangeFilter(lst));
这似乎根本不起作用。有什么想法吗?
简单来说,MultiRowRangeFilter
不适合你的场景
如果担心效率和正确性,我推荐RegexStringComparator
:
int len = String.valueOf(System.currentTimeMillis()).length();
String expr = "^[0-9]{" + len + "}" + String.valueOf(seperator) + vid + "$";
// just kidding... not rely on flag at all.. use 0
int flag = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
RegexStringComparator.EngineType engineType = RegexStringComparator.EngineType.JAVA;
RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,
new RegexStringComparator(expr, flag, engineType));
如果想尝试MultiRowRangeFilter
,开始键应该是0000000000000-vid
,结束键应该是9999999999999-vid
,代码如下:
int len = String.valueOf(System.currentTimeMillis()).length();
String startPrefix = getStrOfRepeatedChar(len, '0'),
endPrefix = getStrOfRepeatedChar(len, '9');
String startRow = startPrefix + String.valueOf(seperator) + wantedId,
endRow = endPrefix + String.valueOf(seperator) + wantedId;
RowRange rowRange = new RowRange(startRow, true, endRow, true);
List<RowRange> rowRangeList = new ArrayList<>();
rowRangeList.add(rowRange);
Filter multiRowRangeFilter = new MultiRowRangeFilter(rowRangeList);
但结果仍然不正确,因为它会在 table.
中显示所有结果
我的 Hbase rowkeys
是这样设置的:timestamp-userid
我需要扫描 hbase 中的所有行和 return 任何 userid = 38356644322545651
所以我们有
vid = "38356644322545651";
目前我正在使用一个小技巧,一个子字符串比较器:
Scan s = new Scan();
Filter f = new RowFilter(CompareOp.EQUAL, new SubstringComparator(vid));
s.setFilter(f);
这很完美!
但是,我质疑检查子字符串是否存在的效率。
此外,如果将来还有其他 rowkeys
包含上述 rowkey
可能会导致问题。
所以我找到了一个叫做 MultiRowRangeFilter
的东西。
看起来很简单。我的实现如下:
Scan s = new Scan();
List<MultiRowRangeFilter.RowRange> lst = new ArrayList<MultiRowRangeFilter.RowRange>();
lst.add(new MultiRowRangeFilter.RowRange("0-" + vid, true, "z-" + vid, true));
s.setFilter(new MultiRowRangeFilter(lst));
这似乎根本不起作用。有什么想法吗?
简单来说,MultiRowRangeFilter
不适合你的场景
如果担心效率和正确性,我推荐RegexStringComparator
:
int len = String.valueOf(System.currentTimeMillis()).length();
String expr = "^[0-9]{" + len + "}" + String.valueOf(seperator) + vid + "$";
// just kidding... not rely on flag at all.. use 0
int flag = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
RegexStringComparator.EngineType engineType = RegexStringComparator.EngineType.JAVA;
RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,
new RegexStringComparator(expr, flag, engineType));
如果想尝试MultiRowRangeFilter
,开始键应该是0000000000000-vid
,结束键应该是9999999999999-vid
,代码如下:
int len = String.valueOf(System.currentTimeMillis()).length();
String startPrefix = getStrOfRepeatedChar(len, '0'),
endPrefix = getStrOfRepeatedChar(len, '9');
String startRow = startPrefix + String.valueOf(seperator) + wantedId,
endRow = endPrefix + String.valueOf(seperator) + wantedId;
RowRange rowRange = new RowRange(startRow, true, endRow, true);
List<RowRange> rowRangeList = new ArrayList<>();
rowRangeList.add(rowRange);
Filter multiRowRangeFilter = new MultiRowRangeFilter(rowRangeList);
但结果仍然不正确,因为它会在 table.
中显示所有结果