The "getRecordsStartingAtKey" action looks up a key in the specified index. When "operator" is set to "=" and the key is an exact match for the key specified by the "indexFilter" property, the action positions the cursor on the matching record and returns the cursor. If the key does not exist, the action returns error 4046 - Key not found. Error 4046 is also returned when the "operator" property is set to ">", "<", ">=", or "<=" but the key provided is outside the range. For example, if "operator" is set to ">" or ">=" and the key provided is larger than the last key in the index, the query would result in an error 4046. Similarly, if "operator" is set to "<" or "<=" and the key provided is smaller than the first key in the index, the query would also result in an error 4046. In both examples, an error is returned because the key provided is outside the range set by the "operator" property, so no records would be returned.
Setting the "operator" property to ">", "<", ">=", or "<=" is the most efficient way to return a few records that are the closest match to a key. Return a cursor when you want to return records before and/or after the closest match, or you want to walk the records starting with the closest matching record. See Most effective ways to return data from the JSON DB API. Returning a cursor and returning records directly are mutually exclusive operations.
Important The index is required and is used to position a cursor to the first record that will be retrieved. Records are retrieved in index order.
Request examples
Minimal
{
"action": "getRecordsStartingAtKey",
"params": {
"tableName": "athlete",
"indexFilter": {
"indexName": "admin_athlete_id_pk",
"operator": "=",
"indexFields": [
{
"fieldName": "id",
"value": "2"
}
]
}
},
"authToken": "replaceWithAuthTokenFromCreateSession"
}Cursor
{
"api": "db",
"requestId": "2",
"action": "getRecordsStartingAtKey",
"params": {
"tableName": "athlete",
"indexFilter": {
"indexName": "admin_athlete_id_pk",
"operator": "=",
"indexFields": [
{
"fieldName": "id",
"value": "2"
}
]
},
"returnCursor": true
},
"authToken": "replaceWithAuthTokenFromCreateSession"
}Maximal
{
"api": "db",
"apiVersion": "1.0",
"requestId": "3",
"action": "getRecordsStartingAtKey",
"params": {
"databaseName": "ctreeSQL",
"ownerName": "admin",
"tableName": "athlete",
"tableFilter": "playerNumber >= 10",
"indexFilter": {
"indexName": "earnings",
"operator": ">=",
"indexFields": [
{
"fieldName": "earnings",
"value": 2000000
}
]
},
"returnCursor": false,
"reverseOrder": false,
"fixedLengthCharFormat": "sql",
"skipRecords": 0,
"maxRecords": -1
},
"responseOptions": {
"includeBookmarks": no,
"binaryFormat": "hex",
"dataFormat": "objects",
"numberFormat": "string",
"variantFormat": "variantObject",
"includeFields": [],
"excludeFields": [
"ranking",
"earnings",
"playerNumber",
"favoriteSaying",
"livedPast2000"
]
},
"debug": "none",
"authToken": "replaceWithAuthTokenFromCreateSession"
}
Response examples
Minimal
{
"result": {
"dataFormat": "objects",
"binaryFormat": "hex",
"fields": [
{
"name": "id",
"type": "bigint",
"length": null,
"scale": null,
"defaultValue": null,
"nullable": false,
"primaryKey": 1,
"autoValue": "incrementOnInsert"
},
{
"name": "changeId",
"type": "bigint",
"length": null,
"scale": null,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "changeId"
},
{
"name": "name",
"type": "varchar",
"length": 30,
"scale": null,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "none"
},
{
"name": "ranking",
"type": "smallint",
"length": null,
"scale": null,
"defaultValue": null,
"nullable": false,
"primaryKey": 0,
"autoValue": "none"
},
{
"name": "birthDate",
"type": "date",
"length": null,
"scale": null,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "none"
},
{
"name": "playerNumber",
"type": "number",
"length": 32,
"scale": 6,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "none"
},
{
"name": "livedPast2000",
"type": "bit",
"length": null,
"scale": null,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "none"
},
{
"name": "earnings",
"type": "money",
"length": 32,
"scale": 4,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "none"
},
{
"name": "favoriteSaying",
"type": "varchar",
"length": 500,
"scale": null,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "none"
}
],
"data": [
{
"birthDate": "1895-02-06",
"changeId": 1291366,
"earnings": 800000,
"favoriteSaying": "Every strike brings me closer to the next home run.",
"id": 2,
"livedPast2000": false,
"name": "Babe Ruth",
"playerNumber": 3,
"ranking": 2
},
{
"birthDate": "1942-01-17",
"changeId": 1291366,
"earnings": 60000000,
"favoriteSaying": "Float like a butterfly, sting like a bee.",
"id": 3,
"livedPast2000": true,
"name": "Muhammad Ali",
"playerNumber": 1,
"ranking": 3
},
{
"birthDate": "1940-10-23",
"changeId": 1291366,
"earnings": 115000000,
"favoriteSaying": "Everything is practice.",
"id": 4,
"livedPast2000": true,
"name": "Pele",
"playerNumber": 10,
"ranking": 4
},
{
"birthDate": "1961-01-26",
"changeId": 1291366,
"earnings": 1720000,
"favoriteSaying": "You miss 100 percent of the shots you never take.",
"id": 5,
"livedPast2000": true,
"name": "Wayne Gretzky",
"playerNumber": 99,
"ranking": 5
},
{
"birthDate": "1969-01-03",
"changeId": 1291366,
"earnings": 990000000,
"favoriteSaying": "Once something is a passion, the motivation is there.",
"id": 6,
"livedPast2000": true,
"name": "Michael Schumacher",
"playerNumber": 1,
"ranking": 6
}
],
"primaryKeyFields": [
"id"
],
"changeIdField": "changeId",
"moreRecords": false,
"requestedRecordCount": 20,
"returnedRecordCount": 5,
"totalRecordCount": 5
},
"errorCode": 0,
"errorMessage": "",
"authToken": "replaceWithAuthTokenFromCreateSession"
}Cursor
{
"result": {
"cursorId": "cursorId",
"totalRecordCount": 6
},
"requestId": "2",
"errorCode": 0,
"errorMessage": "",
"authToken": "replaceWithAuthTokenFromCreateSession"
}Maximal
{
"result": {
"dataFormat": "objects",
"binaryFormat": "hex",
"fields": [
{
"name": "id",
"type": "bigint",
"length": null,
"scale": null,
"defaultValue": null,
"nullable": false,
"primaryKey": 1,
"autoValue": "incrementOnInsert"
},
{
"name": "changeId",
"type": "bigint",
"length": null,
"scale": null,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "changeId"
},
{
"name": "name",
"type": "varchar",
"length": 30,
"scale": null,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "none"
},
{
"name": "birthDate",
"type": "date",
"length": null,
"scale": null,
"defaultValue": null,
"nullable": true,
"primaryKey": 0,
"autoValue": "none"
}
],
"data": [
{
"birthDate": "1940-10-23",
"changeId": "1291366",
"id": "4",
"name": "Pele"
},
{
"birthDate": "1963-02-17",
"changeId": "1291366",
"id": "1",
"name": "Michael Jordan"
}
],
"primaryKeyFields": [
"id"
],
"changeIdField": "changeId",
"moreRecords": false,
"requestedRecordCount": 2,
"returnedRecordCount": 2,
"totalRecordCount": 2
},
"requestId": "3",
"errorCode": 0,
"errorMessage": "",
"authToken": "replaceWithAuthTokenFromCreateSession"
}
Properties
Request properties ("params")
| Property | Description | Default | Type | Limits (inclusive) |
|---|---|---|---|---|
databaseName |
The You specify this property when you want to use a different database instead of the default. This property is useful because objects, such as tables and code packages, can have the same name in multiple databases. This feature allows you to create multiple environments in the same server and reuse the same JSON actions in each environment. For example, you can create It is an error to set If no default database is specified during |
Defaults to the session's "defaultDatabaseName" property |
string | 1 to 64 bytes |
fixedLengthCharFormat |
The
For more details, see |
Optional with default "sql"
|
string |
|
indexFilter |
The
One-field index"indexFilter":
{
"indexName": "name_livedpast2000",
"partialKey": "Mi"
}Multi-field index"indexFilter":
{
"indexName": "name_livedpast2000",
"partialKey": [ "2023-09-22", "Mi" ]
} |
Required - No default value |
object |
|
|
indexFilter .indexFields |
The
"indexFields":
[
{
"fieldName": "name",
"value": "Michael"
},
{
"fieldName": "rank",
"value": "1"
}
] |
Required - No default value | array of objects |
|
|
indexFilter indexFields .fieldName |
The "fieldName" property specifies the name of a field in a table. |
Required - No default value | string | 1 to 64 bytes |
|
indexFilter indexFields .value |
The
In Key-Value actions, the required |
Required - No default value | string |
|
|
indexFilter .indexName |
The "params": {
"indexName": "index1"
} |
Required - No default value |
string | 1 to 64 bytes |
|
indexFilter .operator |
The
The following comparison operators are available:
|
Required - No default value | string |
|
maxRecords |
The "maxRecords" property specifies the maximum number of records to be returned. It is used with "skipRecords" to paginate the results. If the value is not null or omitted, the server returns the maximum number of results specified by "maxRecords". |
Optional with default of 20 |
integer |
-1 to 65535
|
ownerName |
The You specify this property when you want to use a different account instead of the default. Your session's account must have the appropriate privileges to access the code package. This property is useful because objects, such as tables and code packages, can have the same name in the same database as long as different accounts own each object. This feature allows you to create duplicate objects for different users on the same server and reuse the same JSON actions on those objects. For example, an administrator can copy objects from a production environment to her account so she can troubleshoot an issue using the same JSON actions, JavaScript, and SQL code. It is an error to set If no default owner is specified during |
Optional with default of the session's "defaultOwnerName" property |
string | 1 to 64 bytes |
returnCursor |
The
|
Optional with default of false
|
Boolean |
|
reverseOrder |
The
|
Optional with default of false
|
Boolean |
|
skipRecords |
The "skipRecords" property specifies the number of records to skip over when paginating the results. It is used with "maxRecords" to paginate the results. If the value is not null or omitted, the server returns results from the beginning. If it is > 0, the server skips over the specified number of records and returns results starting from that point up until it returns the maximum number of results as defined by "maxRecords". |
Optional with default of 0
|
integer |
0 to 9223372036854775807
|
tableFilter |
The
|
Optional with default of ""
|
string | 0 to unlimited bytes |
tableName |
The See table name in System specifications for the table naming requirements and limitations.
"params": {
"tableName": "ctreeTable"
} |
Required - No default value | string | 1 to 64 bytes |
Response properties ("result")
| Property | Description | Type | Limits (inclusive) |
|---|---|---|---|
binaryFormat |
The "binaryFormat" property designates the format of binary values embedded in JSON strings. See binaryFormat for more details. |
string | One of the following: "base64", "hex", or "byteArray". |
changeIdField |
This property's value designates the name of the field used for change-tracking functionality if you are not using the
However, if you use the name |
string | 1 to 64 bytes |
cursorid |
The
|
string | 0 to 255 bytes |
data |
The |
array of objects | The action determines its contents. |
dataFormat |
The
|
string |
|
fields |
The
"fields": [
{
"autoValue": "none",
"name": "name",
"type": "varchar",
"length": 50,
"scale": null,
"defaultValue": null,
"nullable": false
}
] |
array |
updateRecords and deleteRecords only:
|
|
fields .autoValue |
The "autoValue" property indicates when and how the server automatically sets the field value. See autoValue for more details. |
string |
Some actions only:
|
|
fields .defaultValue |
The "defaultValue" property specifies the default value of a field. |
string | 0 to 65,500 bytes |
|
fields .length |
Identifies the length of the field. | integer |
1 to 65500 |
|
fields .name |
The The The
|
string | 1 to 64 bytes |
|
fields .nullable |
"nullable" identifies whether a field can contain a NULL value. |
Boolean |
|
|
fields .primaryKey |
When > 0, the "primaryKey" property identifies the ordinal position of the field within the table's primary key. |
integer |
0 to 32
|
|
fields .scale |
If the type is "number" or "money", the "scale" property identifies the number of places to the right of the decimal point,. |
integer |
0 to 32
|
|
fields .type |
Identifies the type of the field. See Data types. | string |
|
moreRecords |
The "moreRecords" property indicates if there are more records that match the filters in the request. |
Boolean |
|
primaryKeyFields |
This property specifies the fields of the table’s primary key when multiple fields are combined to form the primary key.
The order of fields in this property is the order of fields in the primary key index. The A primary key with multiple fields has an index named If only one field is used as the primary key, the
Example "primaryKeyFields": [
"a",
"b",
"c"
],
"fields": [
{
"name": "a",
"type": "tinyint"
},
{
"name": "b",
"type": "smallint"
},
{
"name": "c",
"type": "integer"
}
] |
array | an array |
requestedRecordCount |
The
|
integer |
|
returnedRecordCount |
The
|
integer |
|
totalRecordCount |
The
|
integer |
|
Essential information
- Results can be further filtered by a table filter expression, which filters records using any field in the table.
- A table filter is applied after a record is retrieved from the index. The index filter primarily controls which records are returned and the table filter subsequently filters the records.
- Records are returned starting from the matching record position and optionally skipping forward or backward over records to move to a new position.
- The number of records returned can be specified or unlimited.
- This action can also return a cursor, which allows you to use the
"getRecordsFromCursor"action to retrieve a large number of records efficiently. - Results are returned in ascending or descending index order and are formatted as JSON or an array of fields. You can specify which fields and JSON properties are included in the results.
- The
"forceRecordCount"property is not available for this action because the action's purpose is to position the cursor at the first matching record. For the same reason, the"totalRecordCount"property in the response message is-1. - The
"getRecordsStartingAtKey"action directly returns filtered records in index sorted order or returns a cursor that walks the filtered recordset. - It uses an index and an index filter to filter records quickly and efficiently.
- The index filter uses one comparison operator to compare index field values to field values specified in the query.
- It optionally uses a table filter to filter records using values that are not in the index.
- If the database has no matching records to return,
"errorCode": 4046is returned. - An index key may contain multiple fields.
- The index filter works by comparing each indexed field to a field value defined in the query.
- The
"indexFilter"property specifies the comparison value for each indexed field using the properties ("fieldName"and"value") and it defines the comparison operator using the"operator"property.
- The
"getRecordsStartingAtKey"action does not support the"!="operator because that operator does not provide a starting point for getting records.- The
"errorMessage"indicates that"getRecordsByCursor"cannot use a"!="operator. - Instead, use a
"tableFilter"with a"!="comparison.
- The
-
"getRecordsStartingAtKey"directly returns one or more filtered records in index-sorted order. - If the database has no matching records to return,
"errorCode": 4046is returned. - A client uses this action to return records directly when it has a maximum number of records it wants to retrieve in one request.
- The
"getRecordsStartingAtKey"action returns a maximum number of records defined by the"maxRecords"property, after skipping the number of records defined by the"skipRecords"property. - The
"getRecordsStartingAtKey"action supports pagination using"skipRecords"but this is inefficient and slower than returning and using a cursor. - When the
"operator"property is set to">"or">=","getRecordsStartingAtKey"finds and returns each record that has a key in the index that is greater than or greater than or equal to the key specified in"indexFilter".- If at least one matching record is returned, the server sets
"errorCode"to0. - If no matching records are found, the server sets
"errorCode"to4046and the"errorMessage"to"Key not found".
- If at least one matching record is returned, the server sets
- When the
"operator"property is set to"<"or"<=","getRecordsStartingAtKey"finds and returns each record that has a key in the index that is less than or less than or equal to the key specified in"indexFilter".- If at least one matching record is returned, the server sets
"errorCode"to0. - If no matching records are found, the server sets
"errorCode"to4046and the"errorMessage"to"Key not found".
- If at least one matching record is returned, the server sets
- When the
"operator"property is set to"=","getRecordsStartingAtKey"finds and returns each record that has a key in the index that is equal to the key specified in"indexFilter".- A non-unique index may return more than one record.
- A unique index will return zero or one record.
- When one or more records are returned, it sets
"errorCode"to0. - If no matching records are found, the server sets
"errorCode"to4046and the"errorMessage"to"Key not found".
- When returning a cursor, the
"getRecordsStartingAtKey"action sets the starting position of the cursor and sets "errorCode" to an error if the key cannot find a match. - A client uses this action to return a cursor when it has a large number of records it wants to retrieve over multiple requests.
- When the
"operator"property is set to">"or">=","getRecordsStartingAtKey"sets the starting position of the cursor to the closest matching record.- If at least one record exists after the key, the server sets
"errorCode"to0. The matching record can be retrieved using"getRecordsByCursor"with"fetchRecords"set to1. - If no records exists after the key, the server sets
"errorCode"to4046. The"errorMessage"indicates that no records exists after the key and the cursor is set to the end of the record set.
- If at least one record exists after the key, the server sets
- When the
"operator"property is set to"<"or"<=","getRecordsStartingAtKey"sets the starting position of the cursor to the closest matching record.- If at least one record exists prior to the key, the server sets
"errorCode"to0. The matching record can be retrieved using"getRecordsByCursor"with"fetchRecords"set to-1. - If no records exists before the key, the server sets
"errorCode"to4046. The"errorMessage"indicates that no records exists before the key and the cursor is set to the beginning of the record set.
- If at least one record exists prior to the key, the server sets
- When the
"operator"property is set to"=","getRecordsStartingAtKey"sets the cursor to the matching record.- If a match is found, the server sets the cursor to the matching record and sets
"errorCode"to0. The record can be retrieved using"getRecordsByCursor"with"fetchRecords"set to1. - If no matching record is found, the server sets
"errorCode"to4046. The cursor is also set to the first record that has a key value greater than the requested key. The"errorMessage"indicates that no match was found and the cursor is set to the first record that has a key value greater than the requested key.
- If a match is found, the server sets the cursor to the matching record and sets
- Results are returned quickly when retrieving fewer records.
- Results return less quickly when:
- The
"skipRecords"property skips over many records. - The
"tableFilter"property further filters the results.
- The
How to use "getRecordsStartingAtKey"
- Set the
"operator"property to">=". - Set the
"value"property to a partial key value.