edit-icon download-icon

Multiple-row operations

Last Updated: Mar 20, 2018

Table Store offers interfaces for multi-row operations such as BatchGetRow, BatchWriteRow, and GetRange.

Note: The following operation examples are based on synchronous interfaces. See Asynchronous interfaces for more information on how to operate asynchronous interfaces.

BatchGetRow

Batch reads several rows of data from one or more tables.

BatchGetRow can be seen as a set of multiple GetRow operations. Performing each operation, returning the results, and calculating the service capacity unit are all done independently. In comparison with performing a large number of GetRow operations, using BatchGetRow can effectively shorten the request response time and increase the data read rate.

Two possible errors may occur when using BatchGetRow:

  • Overall request error, such as a network error. These errors are stored in the return values of batchGetRow().

  • No overall request error, but some individual rows contain errors. These errors are stored in the results of the corresponding rows.

Example

  1. BatchGetRowRequest req;
  2. {
  3. MultiPointQueryCriterion& criterion = req.mutableCriteria().append();
  4. IVector<MultiPointQueryCriterion::RowKey>& rowkeys = criterion.mutableRowKeys();
  5. {
  6. MultiPointQueryCriterion::RowKey& exist = rowkeys.append();
  7. exist.mutableGet().append() = PrimaryKeyColumn(
  8. "pkey",
  9. PrimaryKeyValue::toStr("some key"));
  10. exist.mutableUserData() = &userDataForSomeKey;
  11. }
  12. {
  13. MultiPointQueryCriterion::RowKey& exist = rowkeys.append();
  14. exist.mutableGet().append() = PrimaryKeyColumn(
  15. "pkey",
  16. PrimaryKeyValue::toStr("another key"));
  17. exist.mutableUserData() = &userDataForAnotherKey;
  18. }
  19. criterion.mutableTable() = "YourTable";
  20. criterion.mutableMaxVersions().reset(1);
  21. }
  22. BatchGetRowResponse resp;
  23. Optional<OTSError> res = client.batchGetRow(resp, req);

Note: Detailed code is available at batchGetRow@GitHub.

BatchWriteRow

Batch insert, modify, or delete several rows of data from one or more tables.

BatchWriteRow can be seen as a set of multiple PutRow, UpdateRow, and DeleteRow operations. Performing each operation, returning the results, and calculating the service capacity unit are all done independently.

Two possible errors may occur when using BatchWriteRow:

  • Overall request error, such as a network timeout. These errors are stored in the return values of batchWriteRow().

  • Errors in individual rows, such as an invalid primary key value. These errors are stored in every row of BatchWriteRowResponse.

Example

  1. static const char kPutRow[] = "PutRow";
  2. static const char kUpdateRow[] = "UpdateRow";
  3. static const char kDeleteRow[] = "DeleteRow";
  4. BatchWriteRowRequest req;
  5. {
  6. // put row
  7. BatchWriteRowRequest::Put& put = req.mutablePuts().append();
  8. put.mutableUserData() = kPutRow;
  9. put.mutableGet().mutableTable() = kTableName;
  10. PrimaryKey& pkey = put.mutableGet().mutablePrimaryKey();
  11. pkey.append() = PrimaryKeyColumn(
  12. "pkey",
  13. PrimaryKeyValue::toStr("row to put"));
  14. }
  15. {
  16. // update row
  17. BatchWriteRowRequest::Update& update = req.mutableUpdates().append();
  18. update.mutableUserData() = kUpdateRow;
  19. update.mutableGet().mutableTable() = kTableName;
  20. PrimaryKey& pkey = update.mutableGet().mutablePrimaryKey();
  21. pkey.append() = PrimaryKeyColumn(
  22. "pkey",
  23. PrimaryKeyValue::toStr("row to update"));
  24. RowUpdateChange::Update& attr = update.mutableGet().mutableUpdates().append();
  25. attr.mutableType() = RowUpdateChange::Update::kPut;
  26. attr.mutableAttrName() = "attr0";
  27. attr.mutableAttrValue().reset(AttributeValue::toStr("some value"));
  28. }
  29. {
  30. // delete row
  31. BatchWriteRowRequest::Delete& del = req.mutableDeletes().append();
  32. del.mutableUserData() = kDeleteRow;
  33. del.mutableGet().mutableTable() = kTableName;
  34. PrimaryKey& pkey = del.mutableGet().mutablePrimaryKey();
  35. pkey.append() = PrimaryKeyColumn(
  36. "pkey",
  37. PrimaryKeyValue::toStr("row to delete"));
  38. }
  39. BatchWriteRowResponse resp;
  40. Optional<OTSError> res = client.batchWriteRow(resp, req);

Note: Detailed code is available at batchWriteRow@GitHub.

GetRange

Read data within the specified primary key range.

RangeIterator is recommended. To construct RangeIterator, you must provide:

  • AsyncClient.

  • RangeQueryCriterion is similar to PointQueryCriterion, but RangeQueryCriterion also requires:

    • Set the starting point (inclusive) and ending point (exclusive) of the range. In addition to the normal primary key value, you can also use two special values: “negative infinity” (strictly less than all normal primary key column values) and “positive infinity” (strictly greater than all primary key column values).

    • Set the reading to positive sequence (values going from small to large) or reverse sequence (values going from large to small). The default setting is positive sequence. When reading in positive sequence, the starting point must be smaller than the ending point. In the reverse sequence, the starting point must be greater than the ending point.

The RangeIterator object is an iterator that provides three interfaces:

  • moveNext() moves the RangeIterator object to the next row. A newly constructed RangeIterator object must call moveNext() to get the value. If reading data fails, moveNext() displays the error in the return value.

  • valid() shows whether the RangeIterator object has reached the ending point of the range.

  • If valid() is true, row objects can be read using get(). You can avoid memory replication by removing the contents of the row object returned by get(). After removing the content, the directly following get() returns the removed content.

Example

  1. RangeQueryCriterion query;
  2. query.mutableTable() = "YourTable";
  3. query.mutableMaxVersions().reset(1);
  4. {
  5. PrimaryKey& start = query.mutableInclusiveStart();
  6. start.append() = PrimaryKeyColumn(
  7. "pkey",
  8. PrimaryKeyValue::toInfMin());
  9. }
  10. {
  11. PrimaryKey& end = query.mutableExclusiveEnd();
  12. end.append() = PrimaryKeyColumn(
  13. "pkey",
  14. PrimaryKeyValue::toInfMax());
  15. }
  16. auto_ptr<AsyncClient> aclient(AsyncClient::create(client));
  17. RangeIterator iter(*aclient, query);
  18. for(;;) {
  19. Optional<OTSError> err = iter.moveNext();
  20. if (err.present()) {
  21. // do something with err
  22. abort();
  23. }
  24. if (!iter.valid()) {
  25. break;
  26. }
  27. Row& row = iter.get();
  28. // do something with row
  29. }

Note: Detailed code is available at GetRange@GitHub.

Read specified columns

Table Store supports infinite row width. Typically, reading the entire row is not required, as reading specified columns is enough.QueryCriterion (PointQueryCriterion, MultiPointQueryCriterion, and RangeQueryCriterion) provides mutableColumnsToGet() to specify columns that must be read. They can be attribute columns or primary key columns. If the value is empty, the entire row is read.

If a specified column does not exist on the read row, the column is missing from the returned result. Table Store does not provide placeholders.

In GetRange, if all specified columns are attribute columns, and a row in the range misses all specified columns, this row does not appear in the result. If this row must be noticed, add the primary key column to the specified columns.

Read specified versions

Each attribute column can contain multiple versions, with each version number (timestamp) corresponding to a column value. When reading, you can define the number of versions (mutableMaxVersions()) and the range of versions (mutableTimeRange()) to be read.

At least one of the maxversions and the range of versions must be defined.

  • If you only define the number of versions, the defined amount of data in all versions is returned, from the newest to the oldest.
  • If you only define the range of versions, all data within this range is returned.
  • If you define both the number of versions and the range of versions, the defined amount of data within the version range is returned, from the newest to the oldest.

Conditional write

In conditional writing, certain conditions have to be checked and met before rows can be written. Table Store guarantees the atomicity of the condition checks and writing.

Table Store supports row existence conditions and column value conditions:

  • Row existence conditions can be divided into the following types:

    • Ignore: This is the default setting whether or not a row exists.
    • ExpectExist: expected to exist. Write if a row exists.
    • ExpectNotExist: expected not to exist. Write if a row does not exist.
  • The column value condition is equivalent to the Filter.

Thank you! We've received your feedback.