Skip to main content

batch

batch lets multiple workers retrieve portions of one cached query result. All workers must sign in as the same user and submit exactly the same query except for the batching parameters. The first worker computes the result; subsequent workers for that user reuse it. Refreshing a session or signing in again preserves the cached result. Each page request must still have a valid session and permission to run the query. The cached result expires 60 seconds after its last access. Each retrieval resets that timer, and a query submitted after expiry recomputes the result.

If the worker computing the result fails, waiting workers receive an error and the failed result is discarded. Retry the batch query to compute a new result. If the failure was caused by that worker’s expired or replaced session, other workers with valid sessions receive a batch failure without being asked to sign in again. A retry computes against the current database, so restart the export rather than combining pages from before and after the failure.

Omitting batch returns an ordinary query result. An empty batch object returns only the total number of matching elements. A batch number with a size or count, or a range, selects a portion of the result. Batch numbers and element indices are zero-based.

Fields and bounds​

The two forms are range or batch_id with exactly one of batches and batch_size. The range form cannot be combined with any other field.

Supplying both batches and batch_size is ambiguous: equal values are rejected, while unequal positive values are accepted but only batches takes effect. This validation limitation does not provide a way to apply both partitioning methods.

Field

Type / required

Behavior

batches

positive integer / conditional

Required with batch_id unless batch_size is used; split the result into this many near-equal batches.

batch_size

positive integer / conditional

Required with batch_id unless batches is used; set the maximum elements in each batch.

batch_id

nonnegative integer / conditional

Required with batches or batch_size; zero-based batch number. A batch beyond the result is empty.

range

array of two nonnegative integers / conditional

Alternative to all other fields: [start, end), with end excluded and both bounds clipped to the result length. Reversed bounds return no elements.

The partition sizes depend on whether the query specifies a batch count or a maximum batch size:

Partition examples

Matching elements

Setting

Partitions

1000

batches: 10

Ten batches of 100 elements.

998

batches: 10

Two batches of 99 elements, followed by eight batches of 100.

1000

batch_size: 10

One hundred batches of 10 elements, with IDs 0 through 99.

998

batch_size: 10

Ninety-nine batches of 10 elements, followed by a final batch of 8.

For 998 matches partitioned with batches: 10, batch_id: 2 returns indices 198 through 297, and batch_id: 9 returns indices 898 through 997. With batch_size: 10, batch 2 returns indices 20 through 29, and batch 99 returns indices 990 through 997.

A range selects element indices directly. [0, 100] returns the first 100 elements. For a result containing 998 elements, [900, 1000] is clipped to the half-open range [900, 998), returning indices 900 through 997.

A command with batch cannot declare _ref. Its result cannot be referenced by subsequent commands in the transaction.

Batch Examples​

An empty batch object returns the total number of matching elements:

[{
"FindEntity": {
"with_class": "PersonBatching_1",
"batch": {
},
"results": {
"list": ["name", "age"]
}
}
}]

The response reports the total count without returning individual objects.

Successful response:

[{
"FindEntity": {
"status": 0,
"batch": {
"total_elements": 100
},
"returned": 0
}
}]

The following query returns batch 18, the nineteenth of 20 batches:

[{
"FindEntity": {
"with_class": "PersonBatching_2",
"batch": {
"batches": 20,
"batch_id": 18
},
"results": {
"list": ["name", "age"]
}
}
}]

If the result has 100 elements, each batch has 5 elements. This returns elements in the half-open range [90, 95), or indices 90 through 94.

Successful response:

[{
"FindEntity": {
"status": 0,
"batch": {
"batch_id": 18,
"batches": 20,
"end": 95,
"start": 90,
"total_elements": 100
},
"entities": [{
"age": 90,
"name": "Person_90"
}, {
"age": 91,
"name": "Person_91"
}, {
"age": 92,
"name": "Person_92"
}, {
"age": 93,
"name": "Person_93"
}, {
"age": 94,
"name": "Person_94"
}],
"returned": 5
}
}]

The following query returns batch 3, the fourth batch of 20 elements:

[{
"FindEntity": {
"with_class": "PersonBatching_3",
"batch": {
"batch_size": 20,
"batch_id": 3
},
"results": {
"list": ["name", "age"]
}
}
}]

For a result with 100 elements, this returns the half-open range [60, 80), or indices 60 through 79.

Successful response:

[{
"FindEntity": {
"status": 0,
"batch": {
"batch_size": 20,
"batch_id": 3,
"end": 80,
"start": 60,
"total_elements": 100
},
"entities": [{
"age": 60,
"name": "Person_60"
}, {
"age": 61,
"name": "Person_61"
}, {
"age": 62,
"name": "Person_62"
}, {
"age": 63,
"name": "Person_63"
}, {
"age": 64,
"name": "Person_64"
}, {
"age": 65,
"name": "Person_65"
}, {
"age": 66,
"name": "Person_66"
}, {
"age": 67,
"name": "Person_67"
}, {
"age": 68,
"name": "Person_68"
}, {
"age": 69,
"name": "Person_69"
}, {
"age": 70,
"name": "Person_70"
}, {
"age": 71,
"name": "Person_71"
}, {
"age": 72,
"name": "Person_72"
}, {
"age": 73,
"name": "Person_73"
}, {
"age": 74,
"name": "Person_74"
}, {
"age": 75,
"name": "Person_75"
}, {
"age": 76,
"name": "Person_76"
}, {
"age": 77,
"name": "Person_77"
}, {
"age": 78,
"name": "Person_78"
}, {
"age": 79,
"name": "Person_79"
}],
"returned": 20
}
}]

A range selects elements directly by their indices:

[{
"FindEntity": {
"with_class": "PersonBatching_4",
"batch": {
"range": [234, 286]
},
"results": {
"list": ["name", "age"]
}
}
}]

For a result with 250 elements, the upper bound is clipped to 250. The query returns the half-open range [234, 250), or indices 234 through 249.

Successful response:

[{
"FindEntity": {
"status": 0,
"batch": {
"range": [234, 286],
"start": 234,
"end": 250,
"total_elements": 250
},
"entities": [{
"age": 234,
"name": "Person_234"
}, {
"age": 235,
"name": "Person_235"
}, {
"age": 236,
"name": "Person_236"
}, {
"age": 237,
"name": "Person_237"
}, {
"age": 238,
"name": "Person_238"
}, {
"age": 239,
"name": "Person_239"
}, {
"age": 240,
"name": "Person_240"
}, {
"age": 241,
"name": "Person_241"
}, {
"age": 242,
"name": "Person_242"
}, {
"age": 243,
"name": "Person_243"
}, {
"age": 244,
"name": "Person_244"
}, {
"age": 245,
"name": "Person_245"
}, {
"age": 246,
"name": "Person_246"
}, {
"age": 247,
"name": "Person_247"
}, {
"age": 248,
"name": "Person_248"
}, {
"age": 249,
"name": "Person_249"
}],
"returned": 16
}
}]