Paginate
Paginate( input, [ts], [after], [before], [size], [events], [sources] )
Paginate( input, [ts], [after], [before], [size], [events], [sources] )
Paginate( input )
Paginate( input, { ["ts": timestamp], ["before": before], ["after": after], ["size": size], ["events": events], ["sources": sources] })
paginate( input, [ts], [after], [before], [size], [events], [sources] )
Paginate( input, [cursor], [ts], [size], [sources], [events] )
Description
Pagination refers to the process of breaking a large set of results into smaller chunks, or pages, that are easier to process. This means that processing an entire result set can involve multiple queries.
A page is a list of results from input
(which has an implicit sort
order) that has a limited size. By default, a page contains up to 64
results, but you can request up to 100,000 results. The limited page
size prevents queries involving many documents from consuming enough
server or client resources that overall performance would be impacted.
When input
is larger than the current page size, only the page size’s
number of results are returned, but the page contains one or two
cursors that can be used in subsequent queries to access the following
or previous pages in the result set. If there are results that follow
the current page, the page contains the after
cursor, which points to
the first entry in the next page. If there are results that come before
the current page, the page contains the before
cursor, which points to
the first entry in the current page.
The other optional parameters influence the pagination in various ways.
ts
can be used to specify a point in time for the results; results
newer than ts
are not included. size
lets you specify the number of
results returned. events
causes the history of the result set to be
reported, rather than just the entries in the set. sources
causes the
result set to include the source for each entry, which is useful when
multiple indexes and/or collections are used.
Parameters
Field name | Field type | Definition and requirements | ||
---|---|---|---|---|
|
A set, or ref, to paginate. |
|||
. |
Optional, default
|
|||
. |
Optional - Return the previous page of results before this cursor (exclusive). |
|||
. |
Optional - Return the next page of results after this cursor (inclusive). |
|||
. |
Optional - default |
|||
. |
Optional - default |
|||
. |
Optional - default |
The parameters Other FQL functions accept a This means that you cannot compose an object, assign it to a variable,
and then use
|
Field name | Field type | Definition and requirements |
---|---|---|
|
A set, or ref, to paginate. |
|
|
Optional - An object that describes the page of results to return. The
object should have a single field, named The cursor object by using the
|
|
|
Optional - default |
|
|
Optional - default |
|
|
Optional - default |
|
|
Optional - default |
Field name | Field type | Definition and requirements |
---|---|---|
|
A set, or ref, to paginate. |
|
|
Optional - default |
|
|
Optional - Return the next page of results after this cursor (inclusive). |
|
|
Optional - Return the previous page of results before this cursor (exclusive). |
|
|
Optional - default |
|
|
Optional - default |
|
|
Optional - default |
Returns
A "builder" object with methods to set additional options. Each "builder" object method accepts one parameter which sets one specific pagination option:
Method name | Parameter type | Definition and requirements |
---|---|---|
|
Optional - default |
|
|
Optional - Return the next page of results after this cursor (inclusive). |
|
|
Optional - Return the previous page of results before this cursor (exclusive). |
|
|
Optional - An object that describes the page of results to return. The
object should have a single field, named |
|
|
Optional - default |
|
|
Optional - default |
|
|
Optional - default |
Each method returns an updated "builder" object after setting its specific option.
When the "builder" object is "resolved", by the end of the query or by using it within a function that accepts a set or array, the pagination results are returned as a Page object.
A Page object.
Page object
A Page
contains an array of results and other decorated elements.
In some cases the entire result set may not fit into the array, so other
fields (the cursor fields) allow you to walk the results set in blocks
(like pages in a book). The cursor fields retrieve blocks of results
before or after the current page of results. When Pages are passed to
functions that accept arrays, only the array element of the Page is
examined or transformed. Other elements of the Page, such as the cursor,
remain unaffected and are passed directly through to the output.
Field | Type | Description |
---|---|---|
|
The elements in the page. |
|
|
The cursor for the next page, inclusive. Optional. |
|
|
The cursor for the previous page, exclusive. Optional. |
Cursor
A cursor is an object used as a marker to indicate a position within a
set. The cursor has a structure identical to the associated index’s
values
field; the same fields with the same types, in the same order.
Cursor matching is prefix-based. That means that if your index contains two or more fields, you only need to specify the first field to achieve a match. You may have to specify additional fields if there are multiple index entries that would match the first field.
A before
cursor indicates the first item in a page of results. It is
used to compute the page of results prior to the before
cursor. The
page before the current page excludes the before
cursor.
An after
cursor indicates the item after the last item in a page of
results. It is used to compute the page of results beginning with the
after
cursor. The page after the current pages includes the after
cursor.
The type of pagination cursor depends on whether the page is from a set, or from an events timeline. Set cursors may be a single scalar value, or an Array of values.
Events timeline cursors may be one of:
It is possible to fetch the last page of a set without knowing how many
pages are available by specifying a synthetic
When you are using the JavaScript driver, which only supports 53-bit
signed integers (instead of 64-bit), the minimum integer to use is
These cursor values work due to the sort precedence. You can always fetch the first page by not specifying a cursor. |
Examples
The following query paginates the set of letters (established in the
Index tutorials), but sets the size
option to 3 to reduce the size of the result set:
Value result = await client.Query(
Paginate(
Documents(Collection("Letters")),
size: 3
)
);
ObjectV(after: Arr(RefV(id = "104", collection = RefV(id = "Letters", collection = RefV(id = "collections")))),data: Arr(RefV(id = "101", collection = RefV(id = "Letters", collection = RefV(id = "collections"))), RefV(id = "102", collection = RefV(id = "Letters", collection = RefV(id = "collections"))), RefV(id = "103", collection = RefV(id = "Letters", collection = RefV(id = "collections")))))
result, err := client.Query(
f.Paginate(
f.Documents(f.Collection("Letters")),
f.Size(3)))
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fmt.Println(result)
}
map[after:[{104 0xc00016e180 0xc00016e180 <nil>}] data:[{101 0xc00016e330 0xc00016e330 <nil>} {102 0xc00016e4e0 0xc00016e4e0 <nil>} {103 0xc00016e690 0xc00016e690 <nil>}]]
System.out.println(
client.query(
Paginate(Documents(Collection("Letters")))
.size(3)
).get());
{after: [ref(id = "104", collection = ref(id = "Letters", collection = ref(id = "collections")))], data: [ref(id = "101", collection = ref(id = "Letters", collection = ref(id = "collections"))), ref(id = "102", collection = ref(id = "Letters", collection = ref(id = "collections"))), ref(id = "103", collection = ref(id = "Letters", collection = ref(id = "collections")))]}
client.query(
q.Paginate(
q.Documents(q.Collection('Letters')),
{ size: 3 }
)
)
.then((ret) => console.log(ret))
.catch((err) => console.error('Error: %s', err))
{ after: [ Ref(Collection("Letters"), "104") ],
data:
[ Ref(Collection("Letters"), "101"),
Ref(Collection("Letters"), "102"),
Ref(Collection("Letters"), "103") ] }
result = client.query(
q.paginate(
q.documents(q.collection("Letters")),
size=3
)
)
print(result)
{'after': [Ref(id=104, collection=Ref(id=Letters, collection=Ref(id=collections)))], 'data': [Ref(id=101, collection=Ref(id=Letters, collection=Ref(id=collections))), Ref(id=102, collection=Ref(id=Letters, collection=Ref(id=collections))), Ref(id=103, collection=Ref(id=Letters, collection=Ref(id=collections)))]}
println(Await.result(
client.query(
Paginate(
Documents(Collection("Letters")),
size = 3
)
),
5.seconds
))
{after: [ref(id = "104", collection = ref(id = "Letters", collection = ref(id = "collections")))], data: [ref(id = "101", collection = ref(id = "Letters", collection = ref(id = "collections"))), ref(id = "102", collection = ref(id = "Letters", collection = ref(id = "collections"))), ref(id = "103", collection = ref(id = "Letters", collection = ref(id = "collections")))]}
The following query repeats the previous query, with the addition of
applying the after
cursor from the previous result to return the next
page of results:
Value result = await client.Query(
Paginate(
Documents(Collection("Letters")),
after: Ref(Collection("Letters"), 104),
size: 3
)
);
ObjectV(before: Arr(RefV(id = "104", collection = RefV(id = "Letters", collection = RefV(id = "collections")))),after: Arr(RefV(id = "107", collection = RefV(id = "Letters", collection = RefV(id = "collections")))),data: Arr(RefV(id = "104", collection = RefV(id = "Letters", collection = RefV(id = "collections"))), RefV(id = "105", collection = RefV(id = "Letters", collection = RefV(id = "collections"))), RefV(id = "106", collection = RefV(id = "Letters", collection = RefV(id = "collections")))))
result, err := client.Query(
f.Paginate(
f.Documents(f.Collection("Letters")),
f.After(f.Ref(f.Collection("Letters"), 104)),
f.Size(3)))
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fmt.Println(result)
}
map[after:[{107 0xc00009a390 0xc00009a390 <nil>}] before:[{104 0xc00009a1e0 0xc00009a1e0 <nil>}] data:[{104 0xc00009a540 0xc00009a540 <nil>} {105 0xc00009a6f0 0xc00009a6f0 <nil>} {106 0xc00009a960 0xc00009a960 <nil>}]]
System.out.println(
client.query(
Paginate(Documents(Collection("Letters")))
.size(3)
.after(Ref(Collection("Letters"), "104"))
).get());
{before: [ref(id = "104", collection = ref(id = "Letters", collection = ref(id = "collections")))], after: [ref(id = "107", collection = ref(id = "Letters", collection = ref(id = "collections")))], data: [ref(id = "104", collection = ref(id = "Letters", collection = ref(id = "collections"))), ref(id = "105", collection = ref(id = "Letters", collection = ref(id = "collections"))), ref(id = "106", collection = ref(id = "Letters", collection = ref(id = "collections")))]}
client.query(
q.Paginate(
q.Documents(q.Collection('Letters')),
{
size: 3,
after: [ q.Ref(q.Collection('Letters'), '104') ],
}
)
)
.then((ret) => console.log(ret))
.catch((err) => console.error('Error: %s', err))
{ before: [ Ref(Collection("Letters"), "104") ],
after: [ Ref(Collection("Letters"), "107") ],
data:
[ Ref(Collection("Letters"), "104"),
Ref(Collection("Letters"), "105"),
Ref(Collection("Letters"), "106") ] }
result = client.query(
q.paginate(
q.documents(q.collection("Letters")),
after = q.ref(q.collection("Letters"), 104),
size=3
)
)
print(result)
{'before': [Ref(id=104, collection=Ref(id=Letters, collection=Ref(id=collections)))], 'after': [Ref(id=107, collection=Ref(id=Letters, collection=Ref(id=collections)))], 'data': [Ref(id=104, collection=Ref(id=Letters, collection=Ref(id=collections))), Ref(id=105, collection=Ref(id=Letters, collection=Ref(id=collections))), Ref(id=106, collection=Ref(id=Letters, collection=Ref(id=collections)))]}
println(Await.result(
client.query(
Paginate(
Documents(Collection("Letters")),
size = 3,
cursor = After(Ref(Collection("Letters"), "104"))
)
),
5.seconds
))
{before: [ref(id = "104", collection = ref(id = "Letters", collection = ref(id = "collections")))], after: [ref(id = "107", collection = ref(id = "Letters", collection = ref(id = "collections")))], data: [ref(id = "104", collection = ref(id = "Letters", collection = ref(id = "collections"))), ref(id = "105", collection = ref(id = "Letters", collection = ref(id = "collections"))), ref(id = "106", collection = ref(id = "Letters", collection = ref(id = "collections")))]}
The following query paginates the set of distinct "spells" documents
with a fire
or water
element:
client.Query(
Paginate(
Union(
Match(Index("spells_by_element"), "fire"),
Match(Index("spells_by_element"), "water")
)
)
);
ObjectV(data: Arr(RefV(id = "181388642046968320", collection = RefV(id = "spells", collection = RefV(id = "collections"))), RefV(id = "181388642071085568", collection = RefV(id = "spells", collection = RefV(id = "collections"))), RefV(id = "181388642088911360", collection = RefV(id = "spells", collection = RefV(id = "collections")))))
result, err := client.Query(
f.Paginate(
f.Union(
f.MatchTerm(f.Index("spells_by_element"), "fire"),
f.MatchTerm(f.Index("spells_by_element"), "water"))))
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fmt.Println(result)
}
map[data:[{181388642046968320 0xc00008e300 0xc00008e300 <nil>} {181388642071085568 0xc00008e4b0 0xc00008e4b0 <nil>} {181388642088911360 0xc00008e660 0xc00008e660 <nil>}]]
System.out.println(
client.query(
Paginate(
Union(
Match(Index(Value("spells_by_element")), Value("fire")),
Match(Index(Value("spells_by_element")), Value("water"))
)
)
).get());
{data: [ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections"))), ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections"))), ref(id = "181388642088911360", collection = ref(id = "spells", collection = ref(id = "collections")))]}
client.query(
q.Paginate(
q.Union(
q.Match(q.Index('spells_by_element'), 'fire'),
q.Match(q.Index('spells_by_element'), 'water'),
)
)
)
.then((ret) => console.log(ret))
.catch((err) => console.error('Error: %s', err))
{
data: [
Ref(Collection("spells"), "181388642046968320"),
Ref(Collection("spells"), "181388642071085568"),
Ref(Collection("spells"), "181388642088911360")
]
}
result = client.query(
q.paginate(
q.union(
q.match(q.index("spells_by_element"), "fire"),
q.match(q.index("spells_by_element"), "water")
)
)
)
print(result)
{'data': [Ref(id=181388642046968320, collection=Ref(id=spells, collection=Ref(id=collections))), Ref(id=181388642071085568, collection=Ref(id=spells, collection=Ref(id=collections))), Ref(id=181388642088911360, collection=Ref(id=spells, collection=Ref(id=collections)))]}
client.query(
Paginate(
Union(
Match(Index("spells_by_element"), "fire"),
Match(Index("spells_by_element"), "water"))))
{data: [ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections"))), ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections"))), ref(id = "181388642088911360", collection = ref(id = "spells", collection = ref(id = "collections")))]}
The following query returns the same set of results as the previous
query, but by setting the sources
option to true
, the source of the
match that included the entry in the set is included in the result:
client.Query(
Paginate(
Union(
Match(Index("spells_by_element"), "fire"),
Match(Index("spells_by_element"), "water")
),
sources: true
)
);
ObjectV(data: Arr(ObjectV(value: RefV(id = "181388642046968320", collection = RefV(id = "spells", collection = RefV(id = "collections"))),sources: Arr(SetRefV(System.Collections.Generic.Dictionary`2[System.String,FaunaDB.Types.Value]))), ObjectV(value: RefV(id = "181388642071085568", collection = RefV(id = "spells", collection = RefV(id = "collections"))),sources: Arr(SetRefV(System.Collections.Generic.Dictionary`2[System.String,FaunaDB.Types.Value]), SetRefV(System.Collections.Generic.Dictionary`2[System.String,FaunaDB.Types.Value]))), ObjectV(value: RefV(id = "181388642088911360", collection = RefV(id = "spells", collection = RefV(id = "collections"))),sources: Arr(SetRefV(System.Collections.Generic.Dictionary`2[System.String,FaunaDB.Types.Value])))))
result, err := client.Query(
f.Paginate(
f.Union(
f.MatchTerm(f.Index("spells_by_element"), "fire"),
f.MatchTerm(f.Index("spells_by_element"), "water")),
f.Sources(true)))
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fmt.Println(result)
}
map[data:[map[sources:[{map[match:{spells_by_element 0xc00011a330 0xc00011a330 <nil>} terms:fire]}] value:{181388642046968320 0xc00011a210 0xc00011a210 <nil>}] map[sources:[{map[match:{spells_by_element 0xc00011a630 0xc00011a630 <nil>} terms:fire]} {map[match:{spells_by_element 0xc000164090 0xc000164090 <nil>} terms:water]}] value:{181388642071085568 0xc00011a510 0xc00011a510 <nil>}] map[sources:[{map[match:{spells_by_element 0xc000164390 0xc000164390 <nil>} terms:water]}] value:{181388642088911360 0xc000164270 0xc000164270 <nil>}]]]
System.out.println(
client.query(
Paginate(
Union(
Match(Index(Value("spells_by_element")), Value("fire")),
Match(Index(Value("spells_by_element")), Value("water"))
)
).sources(Value(true))
).get());
{
data: [
{
value: ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections"))),
sources: [
{
@set = {
match: ref(id = "spells_by_element", collection = ref(id = "indexes")),
terms: "fire"
}
}
]
},
{
value: ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections"))),
sources: [
{
@set = {
match: ref(id = "spells_by_element", collection = ref(id = "indexes")),
terms: "fire"
}
},
{
@set = {
match: ref(id = "spells_by_element", collection = ref(id = "indexes")),
terms: "water"
}
}
]
},
{
value: ref(id = "181388642088911360", collection = ref(id = "spells", collection = ref(id = "collections"))),
sources: [
{
@set = {
match: ref(id = "spells_by_element", collection = ref(id = "indexes")),
terms: "water"
}
}
]
}
]
}
client.query(
q.Paginate(
q.Union(
q.Match(q.Index('spells_by_element'), 'fire'),
q.Match(q.Index('spells_by_element'), 'water'),
),
{ sources: true },
)
)
.then((ret) => console.log(util.inspect(ret, { depth: null })))
.catch((err) => console.error('Error: %s', err))
{
data: [
{
value: Ref(Collection("spells"), "181388642046968320"),
sources: [ Match(Index("spells_by_element"), "fire") ]
},
{
value: Ref(Collection("spells"), "181388642071085568"),
sources: [
Match(Index("spells_by_element"), "fire"),
Match(Index("spells_by_element"), "water")
]
},
{
value: Ref(Collection("spells"), "181388642088911360"),
sources: [ Match(Index("spells_by_element"), "water") ]
}
]
}
result = client.query(
q.paginate(
q.union(
q.match(q.index("spells_by_element"), "fire"),
q.match(q.index("spells_by_element"), "water")
),
sources=True
)
)
print(result)
{'data': [{'value': Ref(id=181388642046968320, collection=Ref(id=spells, collection=Ref(id=collections))), 'sources': [SetRef({'match': Ref(id=spells_by_element, collection=Ref(id=indexes)), 'terms': 'fire'})]}, {'value': Ref(id=181388642071085568, collection=Ref(id=spells, collection=Ref(id=collections))), 'sources': [SetRef({'match': Ref(id=spells_by_element, collection=Ref(id=indexes)), 'terms': 'fire'}), SetRef({'match': Ref(id=spells_by_element, collection=Ref(id=indexes)), 'terms': 'water'})]}, {'value': Ref(id=181388642088911360, collection=Ref(id=spells, collection=Ref(id=collections))), 'sources': [SetRef({'match': Ref(id=spells_by_element, collection=Ref(id=indexes)), 'terms': 'water'})]}]}
client.query(
Paginate(
Union(
Match(Index("spells_by_element"), "fire"),
Match(Index("spells_by_element"), "water")),
sources = true))
{data: [{value: ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections"))), sources: [{@set = {match: ref(id = "spells_by_element", collection = ref(id = "indexes")), terms: "fire"}}]}, {value: ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections"))), sources: [{@set = {match: ref(id = "spells_by_element", collection = ref(id = "indexes")), terms: "fire"}}, {@set = {match: ref(id = "spells_by_element", collection = ref(id = "indexes")), terms: "water"}}]}, {value: ref(id = "181388642088911360", collection = ref(id = "spells", collection = ref(id = "collections"))), sources: [{@set = {match: ref(id = "spells_by_element", collection = ref(id = "indexes")), terms: "water"}}]}]}
The following query returns the same set of results as the first
"spells" query, but by setting the events
option to true
, the events
associated with each item in the set are included in the result:
client.Query(
Paginate(
Union(
Match(Index("spells_by_element"), "fire"),
Match(Index("spells_by_element"), "water")
),
events: true
)
);
ObjectV(data: Arr(ObjectV(ts: LongV(1603756505480000),action: StringV(add),document: RefV(id = "181388642046968320", collection = RefV(id = "spells", collection = RefV(id = "collections")))), ObjectV(ts: LongV(1603756505480000),action: StringV(add),document: RefV(id = "181388642071085568", collection = RefV(id = "spells", collection = RefV(id = "collections")))), ObjectV(ts: LongV(1603756505480000),action: StringV(add),document: RefV(id = "181388642088911360", collection = RefV(id = "spells", collection = RefV(id = "collections"))))))
result, err := client.Query(
f.Paginate(
f.Events(
f.Union(
f.MatchTerm(f.Index("spells_by_element"), "fire"),
f.MatchTerm(f.Index("spells_by_element"), "water")))))
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fmt.Println(result)
}
map[data:[map[action:add document:{181388642046968320 0xc00008f5f0 0xc00008f5f0 <nil>} ts:1603747233890000] map[action:add document:{181388642071085568 0xc00008f7d0 0xc00008f7d0 <nil>} ts:1603747233890000] map[action:add document:{181388642088911360 0xc0001340f0 0xc0001340f0 <nil>} ts:1603747233890000]]]
System.out.println(
client.query(
Paginate(
Union(
Match(Index(Value("spells_by_element")), Value("fire")),
Match(Index(Value("spells_by_element")), Value("water"))
)
).events(Value(true))
).get());
{data: [{ts: 1594322080380000, action: "add", document: ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections")))}, {ts: 1594322080380000, action: "add", document: ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections")))}, {ts: 1594322080380000, action: "add", document: ref(id = "181388642088911360", collection = ref(id = "spells", collection = ref(id = "collections")))}]}
client.query(
q.Paginate(
q.Union(
q.Match(q.Index('spells_by_element'), 'fire'),
q.Match(q.Index('spells_by_element'), 'water'),
),
{ events: true },
)
)
.then((ret) => console.log(ret))
.catch((err) => console.error('Error: %s', err))
{
data: [
{
ts: 1592112564110000,
action: 'add',
document: Ref(Collection("spells"), "181388642046968320")
},
{
ts: 1592112564110000,
action: 'add',
document: Ref(Collection("spells"), "181388642071085568")
},
{
ts: 1592112564110000,
action: 'add',
document: Ref(Collection("spells"), "181388642088911360")
}
]
}
result = client.query(
q.paginate(
q.union(
q.match(q.index("spells_by_element"), "fire"),
q.match(q.index("spells_by_element"), "water")
),
events=True
)
)
print(result)
{'data': [{'ts': 1592874755080000, 'action': 'add', 'document': Ref(id=181388642046968320, collection=Ref(id=spells, collection=Ref(id=collections)))}, {'ts': 1592874755080000, 'action': 'add', 'document': Ref(id=181388642071085568, collection=Ref(id=spells, collection=Ref(id=collections)))}, {'ts': 1592874755080000, 'action': 'add', 'document': Ref(id=181388642088911360, collection=Ref(id=spells, collection=Ref(id=collections)))}]}
client.query(
Paginate(
Union(
Match(Index("spells_by_element"), "fire"),
Match(Index("spells_by_element"), "water")),
events = true))
{data: [{ts: 1594489152910000, action: "add", document: ref(id = "181388642046968320", collection = ref(id = "spells", collection = ref(id = "collections")))}, {ts: 1594489152910000, action: "add", document: ref(id = "181388642071085568", collection = ref(id = "spells", collection = ref(id = "collections")))}, {ts: 1594489152910000, action: "add", document: ref(id = "181388642088911360", collection = ref(id = "spells", collection = ref(id = "collections")))}]}
Is this article helpful?
Tell Fauna how the article can be improved:
Visit Fauna's forums
or email docs@fauna.com
Thank you for your feedback!