Hbase中查找數據一般包括兩種方式:
1) Get方式,通過Rowkey進行查詢。都是獲取一條數據。
2)是通過Scan進行全表查詢,可以設置一些過濾條件,返回一批數據。
Scan查詢的方式:
- scan 可以通過setCaching 與setBatch 方法提高速度(以空間換時間);
- scan 可以通過setStartRow 與setEndRow 來限定范圍([start,end),start 是閉區間,end 是開區間)。范圍越小,性能越高。
- scan 可以通過setFilter 方法添加過濾器,這也是分頁、多條件查詢的基礎。
Scan方式查詢的數據並不是一次全部返回的,是經過多次返回。在客戶端中的Scan代碼,使用for循環遍歷ResultScanner對象獲取數據,每一次都會調用一次next請求,如果在客戶端中有未讀取的數據就返回數據,如果客戶端中沒有數據,next將從服務器端獲取數據,每次默認是100行數據(hbase 0.98)。
如果想要控制每次next請求獲取的數據的量,可以使用以下的參數進行控制:
.setCaching => .setNumberOfRowsFetchSize
(客戶端每次 rpc fetch 的行數).setBatch => .setColumnsChunkSize
(客戶端每次獲取的列數).setMaxResultSize => .setMaxResultByteSize
(客戶端緩存的最大字節數)
Scan的查詢
1、通過Hbase shell中查詢得知,可以使用的Scan中的命令有:
TIMERANGE, FILTER, LIMIT, STARTROW, STOPROW, ROWPREFIXFILTER,
TIMESTAMP,MAXLENGTH, COLUMNS, CACHE, RAW, VERSIONS,
ALL_METRICS, METRICS,REGION_REPLICA_ID, ISOLATION_LEVEL,
READ_TYPE, ALLOW_PARTIAL_RESULTS, BATCH or MAX_RESULT_SIZE
Scan中的有Filter過濾器,通過過濾器進行查詢。
Java 查詢
java查詢可以通過HBase API 實現簡單的增刪查改等功能,但是這些api提供的功能過於簡單,不能實現想MySQL數據庫一樣的按照條件進行查詢。
HBase的Filter的過濾器提供了更加強大的功能,能夠使得HBase能夠根據條件進行過濾查詢。
過濾器的參數
過濾器可以通過數據的行鍵、列組、列、版本號等,通過這些可以高效的完成查詢任務。
使用過濾器的時候,至少需要兩個參數:
1)第一個參數是對數據的比較,比如大於、等於、小於等等比較
2)第二個參數是指將數據以什么樣的類型進行比較,例如說是以bit類型還是String類型進行比較。
過濾器至少需要兩種參數:
1) 抽象的操作符,HBase中提供了枚舉類型表示這種抽象符(CompareFilter.CompareOp
包下的)。HBase的過濾器比較運算符:
LESS <
LESS_OR_EQUAL <=
EQUAL =
NOT_EQUAL <>
GREATER_OR_EQUAL >=
GREATER >
NO_OP 排除所有
- HBase過濾的比較器(指定比價機制)
BinaryComparator 按字節索引順序比較指定字節數組,采用Bytes.compareTo(byte[])
BinaryPrefixComparator 跟前面相同,只是比較左端的數據是否相同
NullComparator 判斷給定的是否為空
BitComparator 按位比較
RegexStringComparator 提供一個正則的比較器,僅支持 EQUAL 和非EQUAL
SubstringComparator 判斷提供的子串是否出現在value中。
過濾器的類型
1、rowKey過濾器RowFilter:根據rowkey進行查詢數據
2、列族過濾器FamilyFilter:根據列族的名字進行查詢符合條件列族下的所有數據
3、列過濾器QualifierFilter:根據條件查詢所有符合的列族中所有數據
4、列值過濾器ValueFilter:根據數據的進行查詢,返回所有符合查詢條件的數據,不管是哪一個列的
// rowkey過濾器
RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.LESS_OR_EQUAL, new BinaryComparator(Bytes.toBytes("0003")));
// 列族過濾器
FamilyFilter familyFilter = new FamilyFilter(CompareFilter.CompareOp.LESS, new SubstringComparator("f2"));
// 列過濾器
QualifierFilter qualifierFilter = new QualifierFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator("name"));
// 列值過濾器
ValueFilter valueFilter = new ValueFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator("8"));
專用過濾器:返回的都是整行數據
1、單列值過濾器 SingleColumnValueFilter:會返回符合條件的整列值的所有字段,也就是返回整個行
2、列值排除過濾器SingleColumnValueExcludeFilter:與SingleColumnValueFilter相反,會排除掉指定的列,返回剩下的列
3、rowkey前綴過濾器PrefixFilter:查詢符合前綴條件的rowkey,也是返回的是整行數據
4、分頁過濾器PageFilter:實現根據指定大的頁數進行過濾
多過濾器綜合查詢FilterList
filterList 就是一個相當於一個list,所添加的過濾器可以是上面的所有過濾器,按照順序添加到filterList中。當查詢數據的時候,數據依次經歷所有的過濾器。
// 單列值過濾器
SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("f1".getBytes(), "name".getBytes(), CompareFilter.CompareOp.EQUAL, "劉備".getBytes());
// 單列值排除過濾器
SingleColumnValueExcludeFilter singleColumnValueExcludeFilter= new SingleColumnValueExcludeFilter("f1".getBytes(), "name".getBytes(), CompareFilter.CompareOp.EQUAL, "劉備".getBytes());
// rowkey的前綴過濾器
PrefixFilter prefixFilter = new PrefixFilter("00".getBytes());
// 分頁過濾器
PageFilter filter = new PageFilter(pageSize);
// 多過濾器綜合查詢
FilterList filterList = new FilterList();
SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("f1".getBytes(), "name".getBytes(), CompareFilter.CompareOp.EQUAL, "劉備".getBytes());
PrefixFilter prefixFilter = new PrefixFilter("00".getBytes());
filterList.addFilter(singleColumnValueFilter);
filterList.addFilter(prefixFilter);
scan.setFilter(filterList);
參考的博客: