表格存储提供了BatchWriteRow、BatchGetRow、GetRange等多行操作的接口。
如果需要了解表格存储各场景的应用案例,请参见快速玩转Tablestore入门与实战。
批量写(BatchWriteRow)
批量写接口用于在一次请求中进行批量的写入操作,也支持一次对多个数据表进行写入。BatchWriteRow操作由多个PutRow、UpdateRow、DeleteRow子操作组成,构造子操作的过程与使用PutRow接口、UpdateRow接口和DeleteRow接口时相同,也支持使用条件更新。
BatchWriteRow的各个子操作独立执行,表格存储会分别返回各个子操作的执行结果。
由于批量写入可能存在部分行失败的情况,失败行的Index及错误信息在返回的BatchWriteRowResponse中,但并不抛出异常。因此调用BatchWriteRow接口时,需要检查返回值,判断每行的状态是否成功;如果不检查返回值,则可能会忽略掉部分操作的失败。
当服务端检查到某些操作出现参数错误时,BatchWriteRow接口可能会抛出参数错误的异常,此时该请求中所有的操作都未执行。
接口
/**
* 批量修改行。
*/
batchWriteRow(params, callback)
参数
- 增加了数据表的层级结构,可以一次处理多个数据表。
tables以数据表为单位组织,后续为各个数据表的操作,设置需要写入、修改或删除的行信息,参数说明请参见单行数据操作。
- 增加了type参数,用于区分操作类型。
操作类型可以为PUT、UPDATE、DELETE。
- 当操作类型为PUT或UPDATE时,primaryKey和attributeColumns有效。
- 当操作类型为DELETE时,primaryKey有效。
示例
批量写入数据。
var client = require('./client');
var TableStore = require('../index.js');
var Long = TableStore.Long;
var params = {
tables: [
{
tableName: 'sampleTable',
rows: [
{
type: 'UPDATE',
condition: new TableStore.Condition(TableStore.RowExistenceExpectation.IGNORE, null),
primaryKey: [{ 'gid': Long.fromNumber(20010) }, { 'uid': Long.fromNumber(20010) }],
attributeColumns: [{ 'PUT': [{ 'col1': 'test3' }, { 'col2': 'test4' }] }],
returnContent: { returnType: 1 }
},
{
type: 'PUT',
condition: new TableStore.Condition(TableStore.RowExistenceExpectation.IGNORE, null),
primaryKey: [{ 'gid': Long.fromNumber(20020) }, { 'uid': Long.fromNumber(20020) }],
attributeColumns: [{ 'col1': 'test1' }, { 'col2': 'test2' }],
returnContent: { returnType: TableStore.ReturnType.Primarykey }
},
{
type: 'DELETE',
condition: new TableStore.Condition(TableStore.RowExistenceExpectation.IGNORE, null),
primaryKey: [{ 'gid': Long.fromNumber(20018) }, { 'uid': Long.fromNumber(20018) }],
}
]
}
],
};
client.batchWriteRow(params, function (err, data) {
if (err) {
console.log('error:', err);
return;
}
console.log('success:', data);
});
详细代码请参见BatchWriteRow@GitHub。
批量读(BatchGetRow)
批量读接口用于一次请求读取多行数据,也支持一次对多个数据表进行读取。BatchGetRow由多个GetRow子操作组成。构造子操作的过程与使用GetRow接口时相同,也支持使用过滤器。
批量读取的所有行采用相同的参数条件,例如ColumnsToGet=[colA],则要读取的所有行都只读取colA列。
BatchGetRow的各个子操作独立执行,表格存储会分别返回各个子操作的执行结果。
由于批量读取可能存在部分行失败的情况,失败行的错误信息在返回的BatchGetRowResponse中,但并不抛出异常。因此调用BatchGetRow接口时,需要检查返回值,判断每行的状态是否成功。
接口
/**
* 批量读取一个或多个表中的若干行数据。
*/
batchGetRow(params, callback)
参数
- 增加了数据表的层级结构,可以一次读取多个数据表的数据。
tables以数据表为单位组织,后续为各个数据表的操作,设置了需要读取的行信息,参数说明请参见单行数据操作。
- primaryKey支持设置多行的主键,可以一次读取多行数据。
示例
批量一次读多个数据表、多行,单行出错时进行重试。
var client = require('./client');
var TableStore = require('../index.js');
var Long = TableStore.Long;
var params = {
tables: [{
tableName: 'sampleTable',
primaryKey: [
[{ 'gid': Long.fromNumber(20013) }, { 'uid': Long.fromNumber(20013) }],
[{ 'gid': Long.fromNumber(20015) }, { 'uid': Long.fromNumber(20015) }]
],
startColumn: "col2",
endColumn: "col4"
},
{
tableName: 'notExistTable',
primaryKey: [
[{ 'gid': Long.fromNumber(10001) }, { 'uid': Long.fromNumber(10001) }]
]
}
],
};
var maxRetryTimes = 3;
var retryCount = 0;
function batchGetRow(params) {
client.batchGetRow(params, function (err, data) {
if (err) {
console.log('error:', err);
return;
}
var isAllSuccess = true;
var retryRequest = { tables: [] };
for (var i = 0; i < data.tables.length; i++) {
var faildRequest = { tableName: data.tables[i][0].tableName, primaryKey: [] };
for (var j = 0; j < data.tables[i].length; j++) {
if (!data.tables[i][j].isOk && null != data.tables[i][j].primaryKey) {
isAllSuccess = false;
var pks = [];
for (var k in data.tables[i][j].primaryKey) {
var name = data.tables[i][j].primaryKey[k].name;
var value = data.tables[i][j].primaryKey[k].value;
var kp = {};
kp[name] = value;
pks.push(kp);
}
faildRequest.primaryKey.push(pks);
} else {
// get success data
}
}
if (faildRequest.primaryKey.length > 0) {
retryRequest.tables.push(faildRequest);
}
}
if (!isAllSuccess && retryCount++ < maxRetryTimes) {
batchGetRow(retryRequest);
}
console.log('success:', data);
});
}
batchGetRow(params, maxRetryTimes);
详细代码请参见BatchGetRow@GitHub。
范围读(GetRange)
范围读接口用于读取一个主键范围内的数据。
范围读接口支持按照确定范围进行正序读取和逆序读取,可以设置要读取的行数。如果范围较大,已扫描的行数或者数据量超过一定限制,会停止扫描,并返回已获取的行和下一个主键信息。您可以根据返回的下一个主键信息,继续发起请求,获取范围内剩余的行。
- 扫描的行数据大小之和达到4 MB。
- 扫描的行数等于5000。
- 返回的行数等于最大返回行数。
- 当前剩余的预留读吞吐量已全部使用,余量不足以读取下一条数据。
接口
/**
* 读取指定主键范围内的数据。
*/
getRange(params, callback)
参数
参数 | 说明 |
---|---|
tableName | 数据表名称。 |
direction | 读取方向。
例如同一表中有两个主键A和B,A<B。如正序读取[A, B),则按从A至B的顺序返回主键大于等于A、小于B的行;逆序读取[B, A),则按从B至A的顺序返回大于A、小于等于B的数据。 |
inclusiveStartPrimaryKey | 本次范围读的起始主键和结束主键,起始主键和结束主键需要是有效的主键或者是由INF_MIN和INF_MAX类型组成的虚拟点,虚拟点的列数必须与主键相同。
其中INF_MIN表示无限小,任何类型的值都比它大;INF_MAX表示无限大,任何类型的值都比它小。
数据表中的行按主键从小到大排序,读取范围是一个左闭右开的区间,正序读取时,返回的是大于等于起始主键且小于结束主键的所有的行。 |
exclusiveEndPrimaryKey | |
limit | 数据的最大返回行数,此值必须大于 0。
表格存储按照正序或者逆序返回指定的最大返回行数后即结束该操作的执行,即使该区间内仍有未返回的数据。此时可以通过返回结果中的nextStartPrimaryKey记录本次读取到的位置,用于下一次读取。 |
columnsToGet | 读取的列集合,列名可以是主键列或属性列。
如果不设置返回的列名,则返回整行数据。 说明
|
maxVersions | 最多读取的版本数。
说明 maxVersions与timeRange必须至少设置一个。
|
timeRange | 读取版本号范围或特定版本号的数据。更多信息,请参见TimeRange。
说明 maxVersions与timeRange必须至少设置一个。
specificTime和 时间戳的单位为毫秒,最小值为0,最大值为Long.MAX_VALUE。 |
columnFilter | 使用过滤器,在服务端对读取结果再进行一次过滤,只返回符合过滤器中条件的数据行。更多信息,请参见过滤器。
说明 当columnsToGet和columnFilter同时使用时,执行顺序是先获取columnsToGet指定的列,再在返回的列中进行条件过滤。
|
nextStartPrimaryKey | 根据返回结果中的nextStartPrimaryKey判断数据是否全部读取。
|
示例
按照范围读取数据。
var Long = TableStore.Long;
var client = require('./client');
var params = {
tableName: "sampleTable",
direction: TableStore.Direction.FORWARD,
inclusiveStartPrimaryKey: [{ "gid": TableStore.INF_MIN }, { "uid": TableStore.INF_MIN }],
exclusiveEndPrimaryKey: [{ "gid": TableStore.INF_MAX }, { "uid": TableStore.INF_MAX }],
limit: 50
};
client.getRange(params, function (err, data) {
if (err) {
console.log('error:', err);
return;
}
//如果data.next_start_primary_key不为空,则继续读取。
if (data.next_start_primary_key) {
}
console.log('success:', data);
});
详细代码请参见GetRange@GitHub。