Pagination
Pagination allows you to control the result set that comes back from Cloud CMS for any operations that produce
a list of items. It is called pagination because it gives you a way to organize your record set into pages
and then get those pages back, one at a time.
Pagination gives you a way to adjust the result set before it is sent over the wire (and back to you)
so that you can have smaller "paged" payloads. Pagination is useful because, most of the time, unless
the result set is very small, you're not going to be interested in dealing with all of the items at once.
For example, with pagination, you can do things like query for all of the users in a domain. You might be
interested in presenting them on the screen. Let's imagine there are 10,000 users. Well, chances are you
probably don't want to show 10,000 users on the screen all at once. Instead, maybe you'd like to only show
50 at a time. Pagination lets you tell Cloud CMS to hand back 50 starting at index 0. Or jump ahead to index
9017 and give back the next 50 (i.e. users 9017 through 9066). That way, you're only getting 50 users at a
time. However, you can get back a different 50 each time, as you web application user clicks forward and back.
Fundamentally, pagination lets you adjust two important properties:
skip
- how many records you'd like to skip ahead in the total result set before handing back.limit
- how many records in total you'd like to have sent over the wire.
Suppose you ran a query and wanted to retrieve the first 10 items. You might specify:
skip = 0
limit = 10
You could then later retrieve the next 10 items by specifying:
skip = 10
limit = 10
The record set response from Cloud CMS contains information that you can use to determine the total number of results
as well as offset information. For example, a response might come back that essentially looks something like this:
{
"rows": [{
"_doc": "d0977d2194dfcb8eec61",
...
}, {
"_doc": "d0977d2194dfcb8eec62",
...
}],
"size": 10,
"total_rows": 45,
"offset": 0
}
Where:
size
is the number of records returned (i.e. the size of therows
array)total_rows
is the total number of matching results in the queryoffset
is the index into the results where things were handed back (i.e. theskip
you passed in)
For more information on how this works, please read up on the Collections Envelope in the API.
Sorting
Pagination also lets you define how the record set should be sorted before it is handed back. The sorting
is taken into account during query or lookup time so that the actual cursor into the underlying database is
used to optimize performance.
You can sort on zero or more fields. For each field, you can choose to sort in ascending (1) or descending (-1)
order. You specify this by passing a JSON object that defines this for any and all fields.
For example, the following could be used to sort users first by their name and second by a nested custom
property:
{
"name": 1,
"company.name": -1
}
By default, sorting is performed using a fast ASCII comparison that is not sensitive to locale. Each value being compared
is essentially treated as a string and the internal ASCII values for each character are compared. As such, the default
sort behavior is case-sensitive and not particular to any given locale.
For many cases, this will provide you with what you want. However, if you require locale-specific treatment of strings
and numeric values, please read on.
Sorting Options
Starting with Cloud CMS version 4.0 and beyond, advanced sorting options are available that you can use to
finely control locale-specific sort order and sort behavior.
These options are:
locale
- (required) the locale code to assume when dealing with strings and numbers on any sorted fieldsnumericOrdering
- true or false - whether to treat numbers in strings as their numeric values (instead of strings)caseFirst
- eitherupper
orlower
indicating that you wish for case-sensitive sorting with preference to either uppercase or lowercase characters.
Written as JSON, these options may look like:
{
"locale": "en_US",
"numeringOrdering": true,
"caseFirst": "lower"
}
The only required option is locale
. If only locale
is specified, the sorting will be case-insensitive and carried out according
to the expectations of that locale.
Locale
These advanced sorting options fundamentally require that you tell Cloud CMS the locale
to assume for any data that
it needs to sort on. This is necessary since Cloud CMS allows you to store content in many locales all at once. For
example, two nodes stored in Cloud CMS could be in two entirely different locales but may have the same content type and
same properties. Or you might have a single node with multiple properties, each with content of a different locale.
By telling Cloud CMS the locale
to assume during the sort, Cloud CMS can apply some locale-specific logic to the sort.
This is especially useful when working with character sets (such as Swedish or French) where accented characters are
present and those characters may be required to be sorted in an expected order.
For example, in French, we might have the following words:
cote, coté, côte, côté
If sorted descending using a normal ASCII approach (i.e. not using Options), we'd get the default order. This
order would be:
côté, côte, coté, cote
If we tell Cloud CMS to be mindful of the French locale (fr
), we will get back a different order. This is the
expected order of results taking into consideration the accents of the French language.
côté, coté, côte, cote
Some languages require words to be ordered on the secondary level according to the last accent difference, as opposed
to the first accent difference. Canadian French happens to be one of these cases. If we tell Cloud CMS to sort results
for Canadian French (fr_CA
), we'll get back a different result as well:
côté, côte, coté, cote
You can pass any locale you wish using the locale
attribute. In most cases, the locale
will be stripped down to
just its language code. However, in some cases, there are country and language code combinations that have specific
sorting rules (such as with Canadian French above). Cloud CMS will make a best effort to determine the locale that
is applicable based on what you pass in.
For a full list of supported locales, see:
https://docs.mongodb.com/manual/reference/collation-locales-defaults/#supported-languages-and-locales
Cloud CMS also supports variants as noted in the link above. Where applicable, you can specify a variant of a locale
by using the following structure:
<locale code>@collation=<variant>
For example, to sort in Chinese using the pinyin
variant, you could set locale
to zh@collation=pinyin
.
Once you've specified the locale, there are a few additional optimizations you can provide as listed below.
Numeric Ordering
You may opt to turn on Numeric Ordering in order to have any numbers represented in your sorted fields treated as
numerals instead of strings.
For example, you might have the following data:
1 James St
5 James St
10 James St
2 James St
20 James St
50 James St
If you sorted this ascending using the normal ASCII approach, you'd get back a result set that treats each element as a string.
The numbers inside the string are not taken into consideration and you'd get back something like this:
1 James St
10 James St
2 James St
20 James St
5 James St
50 James St
However, if you tell Cloud CMS that the locale
is en
(English) and enable numericOrdering
(set to true
), you
will get back the following results:
1 James St
2 James St
5 James St
10 James St
20 James St
50 James St
Which is what any normal, every day human being in this sector of the milky way galaxy would expect when sorting the
aforementioned data. The numericOrdering
option makes it so that the numbers inside of the string are treated
individually and introduces a numeric comparison between values.
Case First
You may opt to turn on Case First behaviors in order to adjust the sort results for cases where there are collisions
on case between strings.
For example, suppose you have the following:
PIRATES OF THE CARIBBEAN
pirates of the caribbean
Pirates of the Caribbean
Thunder Mountain Railroad
thunder mountain railroad
THUNDER MOUNTAIN RAILROAD
HAUNTED MANSION
haunted mansion
Haunted Mansion
If you sorted this ascending using the normal ASCII approach, you'd get back this:
haunted mansion
Haunted Mansion
HAUNTED MANSION
pirates of the caribbean
Pirates of the Caribbean
PIRATES OF THE CARIBBEAN
thunder mountain railroad
Thunder Mountain Railroad
THUNDER MOUNTAIN RAILROAD
If you sort ascending but set caseFirst
to upper
, you would get back the following:
HAUNTED MANSION
Haunted Mansion
haunted mansion
PIRATES OF THE CARIBBEAN
Pirates of the Caribbean
pirates of the caribbean
THUNDER MOUNTAIN RAILROAD
Thunder Mountain Railroad
thunder mountain railroad
If you sort ascending but set caseFirst
to lower
, you would get back the following:
haunted mansion
Haunted Mansion
HAUNTED MANSION
pirates of the caribbean
Pirates of the Caribbean
PIRATES OF THE CARIBBEAN
thunder mountain railroad
Thunder Mountain Railroad
THUNDER MOUNTAIN RAILROAD
Note that, in this case, the default ASCII and lower
sorts are the same. This will be the case for cases where
the character keycodes (ASCII) are already naturally sorted via keycode.
For non-English languages that have accented characters and larger character sets, the expected sort orders will differ.
Be sure to use lower
in this case to get proper lowercase sorting for the desired locale.
REST API
parameters.
For example, the following would hand back a list of 10 principals from a domain starting at index 5 in the
result set. There may 1,000 users overall, but you'd only get back 10 (numbers 5 through 14).
GET http://api.cloudcms.com/domains/domainId/principals?skip=5&limit=10
We can also pass sorting information along (as a serialized JSON object):
GET http://api.cloudcms.com/domains/domainId/principals?skip=5&limit=10&sort={"name":1,"company.name":-1}
We can also pass pagination options along (as a serialized JSON object):
GET http://api.cloudcms.com/domains/domainId/principals?skip=5&limit=10&options={"locales": "fr_FR"}
GET http://api.cloudcms.com/domains/domainId/principals?skip=5&limit=10&options={"locales": "fr_FR", "caseFirst": "lower"}
GET http://api.cloudcms.com/domains/domainId/principals?skip=5&limit=10&options={"locales": "fr_FR", "caseFirst": "lower", "numericOrdering": true}
Driver methods
You can also pass pagination information via driver methods. Most drivers support pagination as an optional
argument into methods that produce lists of objects.
Here we retrieve the same list of 10 users from a domain starting from index 5.
var domain = ...;
domain.listUsers({
"skip": 5,
"limit": 10
});
Here we retrieve the same list but we sort by name
and company.name
:
var domain = ...;
domain.listUsers({
"skip": 5,
"limit": 10,
"sort": {
"name": 1,
"company.name": -1
}
});
We can also perform custom queries and paginate the results:
var domain = ...;
domain.queryUsers({
"company.name": "Assan Motors"
},{
"skip": 5,
"limit": 10,
"sort": {
"name": 1,
"company.name": -1
}
});