Scanner and filter operations
Scanner are the most efficient way to retrieve multiple rows and columns from HBase. For scalability reasons, this module implements internally the native Node.js Stream Readable API.
Grab an instance of "Scanner"
const myScanner = hbase({}).getTable('my_table').scan(...)
Or
const client = new hbase.Client({})
const myScanner = new hbase.Scanner(client, {table: 'my_table'})
Options
All options except the "table" option are optional. The following properties are available:
startRow
First row returned by the scanner.endRow
Row stopping the scanner, not returned by the scanner.columns
Filter the scanner by columns (a string or an array of columns).batch
Number of cells returned on each iteration, internal use, default to "1000".maxVersions
Number of returned version for each row.startTime
Row minimal timestamp (included).endTime
Row maximal timestamp (excluded).filter
See below for more information.encoding
Default to client.options.encoding, set to null to overwrite default encoding and return a buffer.
Using the Stream Readable API
The Stream Readable API is a scalable solution to throttle the iteration of large volumes of data. By large, we mean a volume exceeding the memory capacity of the node hosting the process.
const scanner = client
.table('node_table')
.scan({
startRow: 'test_scanner_get_startRow_11',
maxVersions: 1
})
const rows = []
scanner.on( 'readable', => {
while(chunk = scanner.read())
rows.push chunk
})
scanner.on( 'error', err =>
throw err
)
scanner.on( 'end', =>
console.info(rows)
)
Using the callback API
For convenience, the scan
function exported by the table object accepts a callback function which will be called when the scan has completed. Be warned, using a callback implies that the returned data set must fit in memory.
client
.table('node_table')
.scan({
startRow: 'test_scanner_get_startRow_11',
maxVersions: 1
}, (err, rows) =>
console.info(rows)
)
Using filter
Filter are defined during the scanner creation. If you are familiar with HBase filters, it will be real easy to use them. Note, you should not worry about encoding the values, the library will do it for you. When you create a new scanner, just associate the filter
property with your filter object. All filters are supported.
Many examples are available in the tests but here's one which returns all rows starting by "mykey" and whose value is "here you are".
client
.table('my_tb')
.scan({
filter: {
"op":"MUST_PASS_ALL","type":"FilterList","filters":[{
"op":"EQUAL",
"type":"RowFilter",
"comparator":{"value":"my_key_.+","type":"RegexStringComparator"}
},{
"op":"EQUAL",
"type":"ValueFilter",
"comparator":{"value":"here you are","type":"BinaryComparator"}
}
]}
}, (error, cells) => {
assert.ifError(error)
});
API: scanner.init
Internal method to create a new scanner and retrieve its ID.
API: scanner.get
Internal method to retrieve a batch of records.
myScanner.get(callback)
The method is expected to be called multiple time to get the next cells from HBase. The callback is required and receive two arguments, an error object if any and a array of cells or null if the scanner is exhausted.
The number of cells depends on the batch
option. It is your responsibility to call get
as long as more cells are expected.
API: scanner.delete
Internal method to unregister the scanner from the HBase server.
myScanner.delete(callback)
The callback is optional and receives two arguments, an error object if any and a boolean indicating whether the scanner was removed or not.
API: scanner._read(size)
Implementation of the stream.Readable
API.