HBase数据库scan操作_HBase Scan 使用

一、 Scan类常用方法说明

1.指定需要的family或column,

如果没有调用任何addFamily或Column,会返回所有的columns

scan.addFamily()
scan.addColumn()

2.指定最大的版本个数。

如果不带任何参数调用setMaxVersions,表示取所有的版本。如果不掉用setMaxVersions,只会取到最新的版本

scan.setMaxVersions()

3.指定最大的时间戳和最小的时间戳,

只有在此范围内的cell才能被获取

scan.setTimeRange()

4.指定时间戳

scan.setTimeStamp()

5.指定开始的行。

如果不调用,则从表头开始

scan.setStartRow()

6.指定结束的行(不含此行)

scan.setStopRow()

7.指定最多返回的Cell数目。

用于防止一行中有过多的数据,导致OutofMemory错误

scan.setBatch()

8.指定Filter来过滤掉不需要的信息

scan.setFilter()

二、比较运算符

HBase 内置以下7种比较运算符,在比较过滤器中需要用到比较运算符

public enum CompareOperator {
	LESS,
	LESS_OR_EQUAL,
	EQUAL,
	NOT_EQUAL,
	GREATER_OR_EQUAL,
	GREATER,
	NO_OP;
	private CompareOperator() {}
}

三、比较器

通过比较器可以实现多样化目标匹配效果,比较器有以下子类可以使用

BinaryComparator // 匹配完整字节数组
BinaryPrefixComparator // 匹配字节数组前缀
BitComparator // 按位执行与、或、异或比较
NullComparator // 判断当前值是不是 NULL
RegexStringComparator // 正则表达式匹配字符串
SubstringComparator // 子串匹配,相当于 contains(),大小写不敏感

四、 Filter 过滤器

FilterList 代表一个过滤器列表,可以对多个Filter进行组合使用

FilterList.Operator.MUST_PASS_ALL --> and

FilterList.Operator.MUST_PASS_ONE --> or

Scan scan = new Scan();

Filter filter1 = new ...;

Filter filter2 = new ...;

Filter filter3 = new ...;

ilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);

scan.setFilter(list);

(1) 比较过滤器

1)行键过滤器 RowFilter

筛选出匹配的所有的行,基于行键(Rowkey)过滤数据,可以执行精确匹配,子字符串匹配或正则表达式匹配,过滤掉不匹配的数据

一般来说,对 Rowkey 进行范围过滤,可以执行 Scan 的 startKey 和 endKey,RowFilter 可以更精确的过滤

Scan scan = new Scan();
RowFilter rowFilter = new RowFilter(CompareOperator.EQUAL, newBinaryComparator(Bytes.toBytes("00001")));
scan.setFilter(rowFilter);

2) 列族过滤器 FamilyFilter

与 RowFilter 类似,区别是比较列族,而不是比较行键。当HBase表有多个列族时,可以用来筛选不同列族中的列

Scan scan = new Scan();
FamilyFilter familyFilter = new FamilyFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("info")));
scan.setFilter(familyFilter);

3)列名过滤器 QualifierFilter

根据列名进行筛选

Scan scan = new Scan();
QualifierFilter qualifierFilter = new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("userName")));
scan.setFilter(qualifierFilter);

4)值过滤器 ValueFilter

筛选特定值的单元格,可以与 RegexStringComparator 搭配使用,完成复杂的筛选

不同的比较器,只能与部分比较运算符搭配,例如 SubstringComparator 只能使用 EQUAL 或 NOT_EQUAL

Scan scan = new Scan();
ValueFilter valueFilter = new ValueFilter(CompareOperator.NOT_EQUAL, new BinaryComparator(Bytes.toBytes("zhangsan")));
scan.setFilter(valueFilter);

5)DependentColumnFilter

一种更复杂的过滤器,不止简单的通过用户指定的信息筛选数据。允许指定一个参考列或引用列,使用参考列控制其他列的过滤。该过滤器会使用参考列的时间戳,并在过滤时包括所有与引用时间戳相同的列。

参考列过滤器相当于一个 ValueFilter 和一个时间戳过滤器的组合。

Scan scan = new Scan();
Filter dependentColumnFilter = new DependentColumnFilter(
		Bytes.toBytes("cf-d"),
		Bytes.toBytes("col-1"),
		false,
		CompareOperator.EQUAL,
		new BinaryComparator(Bytes.toBytes("val-1")));
scan.setFilter(filter);

(2) 专用过滤器

1)单列值过滤器 SingleColumnValueFilter

使用某一列的值,决定一行数据是否被过滤

对于不包含指定列的行数据,通过 setFilterIfMissing() 决定是否返回

Scan scan = new Scan();
Filter filter = new SingleColumnValueFilter(Bytes.toBytes("info"),Bytes.toBytes("id"), CompareOperator.EQUAL,Bytes.toBytes("1234"));
scan.setFilter(filter);

2) 单列值排除器 SingleColumnValueExcludeFilter

继承自 SingleColumnValueFilter,实现的与单列值过滤器相反的语义

Scan scan = new Scan();
Filter filter = new SingleColumnValueExcludeFilter(Bytes.toBytes("info"),Bytes.toBytes("id"), CompareOperator.EQUAL,Bytes.toBytes("1234"));
scan.setFilter(filter);

3)行前缀过滤器 PrefixFilter

基于行键(Rowkey)的前缀过滤行数据。Scan 操作以字典序查找,当行键大于前缀时,Scan 结束

Scan scan = new Scan();
Filter filter = new PrefixFilter(Bytes.toBytes("row1"));
scan.setFilter(filter);

4) 列前缀过滤器 ColumnPrefixFilter

通过对列名称的前缀匹配过滤,返回的结果只包含满足过滤器的列

Scan scan = new Scan();
ColumnPrefixFilter filter1 = new ColumnPrefixFilter(Bytes.toBytes("param"));
scan.setFilter(filter1);

5)列多前缀过滤器 MultipleColumnPrefixFilter

和ColumnPrefixFilter行为差不多,但可以指定多个前缀

Scan scan = new Scan();
byte[][] bytes = new byte[][]{Bytes.toBytes("param")};
MultipleColumnPrefixFilter columnPrefixFilter = new MultipleColumnPrefixFilter(bytes);
scan.setFilter(columnPrefixFilter);

6)分页过滤器 PageFilter

使用该过滤器,对结果进行按行分页,需要指定 pageSize 参数,控制每页返回的行数,并设置 startRow 多次调用 getScanner()

只适用于一些特殊场景,性能也并不高

Connection connection;
Table table = null;
try {
	connection = ConnectionFactory.createConnection(new 		Configuration());
	table = connection.getTable(TableName.valueOf("test"));
} catch (IOException e) {
	e.printStackTrace();
}
byte[] lastRow = null;
// 每页10条数据
Filter pageFilter = new PageFilter(10);
int rowCount = 0;
while(rowCount < 10) {
	Scan scan = new Scan();
	scan.setFilter(pageFilter);
	scan.withStartRow(lastRow);
	ResultScanner resultScanner;
	try {
		assert table != null;
		resultScanner = table.getScanner(scan);
		for (Result result : resultScanner) {
			// ...

			// 记录最后一行的rowKey
			lastRow = result.getRow();
			// 记录本页行数
			rowCount++;
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}

7)行键过滤器 KeyOnlyFilter

这个 Filter 只会返回每行的行键+列簇+列,而不返回值(value),对不需要值的应用场景来说,非常实用,减少了值的传递。构造方法可以设置lenAsValue参数(默认false),表示返回时,value 设为原列值的长度

KeyOnlyFilter filter = new KeyOnlyFilter();
KeyOnlyFilter filter = new KeyOnlyFilter(true);

8)首次行键过滤器 FirstKeyOnlyFilter

这个 Filter 仅仅返回每一行中的第一个cell的值,可以用于高效的执行行数统计操作,在扫描到第一个 cell 时,立即跳到下一行数据,性能相比全表扫描得到提升

FirstKeyOnlyFilter filter = new FirstKeyOnlyFilter();

9)包含结束的过滤器 InclusiveStopFilter

一般的扫描结果中,设置一个开始行键和一个终止行键,是前闭后开区间,不包含结束行,使用这个过滤器时将结束行加入到结果中

Filter filter = new InclusiveStopFilter(Bytes.toBytes("uid-10"));

10)时间戳过滤器 TimestampsFilter

当需要在扫描结果中对版本进行细粒度控制时,可以使用这个Filter 传入一个时间戳集合,对时间进行限制,只会返回与指定时间戳相同的版本数据,并且与设置时间戳范围共同使用

Scan scan = new Scan();
Filter filter = new TimestampsFilter(Arrays.asList(5L, 10L, 15L));
scan.readVersions(3);
scan.setFilter(filter);
Scan scan2 = new Scan();
scan2.readVersions(3);
scan2.setFilter(filter);
scan2.setTimeRange(8L, 12L);

11)列计数过滤器 ColumnCountGetFilter

使用这个过滤器,限制每行最多返回多少列。注意当一行的列数达到设定的最大值,过滤器会停止 Scan 操作,所以不适合全表扫描,适合在 Get 方法中使用

Scan scan = new Scan();
Filter filter = new ColumnCountGetFilter(10);
scan.setFilter(filter);

12)列分页过滤器 ColumnPaginationFilter

与 PageFilter 类似,可以对一行的所有列进行分页,需要传入偏移量 offset 和返回数量 limit

ColumnPaginationFilter(int limit, int offset)
Scan scan = new Scan();
Filter filter = new ColumnPaginationFilter(10,5);
scan.setFilter(filter);

13)随机行过滤器 RandomRowFilter

这个 Filter 可以使结果中包含随机行,参数 chance 取值在 0.0 到 1.0 之间,表示随机取行数的比例,每一行会调用 Random.nextFloat() 与 chance 比较来确定是否被过滤

Scan scan = new Scan();
Filter filter = new RandomRowFilter(0.5F)
scan.setFilter(filter);

(3)其他过滤器

普通过滤器可以提供对返回结果的筛选限制,一些额外的控制可以附加在过滤器上

1)跳转过滤器 SkipFilter

包装了用户的一个过滤器,当过滤器发现某一行的一列需要过滤时,整行数据都被过滤掉。

下面的例子是,使用 SkipFilter 和 ValueFilter 组合,获取不等于指定列值的行,同时过滤掉其他不符合条件的行(即只要有一行中一列的值等于“val-0”,就会被过滤)

Scan scan = new Scan();
Filter filter1 = new ValueFilter(CompareFilter.CompareOp.NOT_EQUAL,new BinaryComparator(Bytes.toBytes("val-0")));
Filter filter2 = new SkipFilter(filter1);

2)全匹配过滤 WhileMatchFilter

与SkipFilter 相似,不过当一条数据被过滤掉时,会停止 Scan 操作。可以用来检查全表数据中,是否有某些数据不符合条件

Scan scan = new Scan();
Filter filter1 = new ValueFilter(CompareFilter.CompareOp.NOT_EQUAL,new BinaryComparator(Bytes.toBytes("val-0")));
Filter filter2 = new WhileMatchFilter(filter1);
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值