Ordering

Learn how models of various types are ordered and returned from query results.

Default

Every model type has a natural / default ordering field and direction.

Universal, Content, and User Profile types order by their created timestamp, ascending from oldest to newest.

However keep in mind that ordered versus unordered results are also influenced by the type of query.

Custom

The Universal type supports custom ordering for the following field types:

string, integer, double, timestamp, date

To specify custom natural ordering on one of these field types use the order attribute set to true.

highScore:
  type: integer
  order: true

Contained Models

If a model is a child within a container, then the field names which allow custom ordering are limited to title, name, order, hierarchy.

Query Ordering

The default ordering of results is impacted by the type of query performed.

"All" / all()

Results are ordered using the default natural order of the model type. all() may also be explicitly ordered with asc() or desc().

Field Criteria

Results for field specific query criteria are unordered by default.

Ordering of field queries may be activated with asc() or desc(). However we recommend minimizing their use in this case, and relying on the unordered behavior. The typical goal of field specific query criteria is to return a relatively small set of results, at which point client side ordering is also a possibility.

Hierarchy

The hierarchy field type provides custom, manual ordering of the Universal model type. When specified on a Universal model, it automatically changes the natural ordering to use this field.

Hierarchy values may be used to represent simple custom ordering, and optionally more complex nested ordering scenarios.

In contrast to a plain numeric field, hierarchy values provide efficient reordering of a single model value, without causing all other model values before and after to be reordered / updated.

Values

Hierarchy fields are ultimately represented as value objects with various methods for traversing and manipulating the hierarchy.

However they may also be assigned and represented as plain strings. For example, /1/, /2/, and so on.

Typically when working with hierarchy values it's not necessary to think about the resulting string value. Instead use the available value methods to traverse and manipulate exiting hierarchy values relative to one another.

Initialization

When using init: true with a hierarchy field, new models will automatically be assigned the next hierarchy value.

The first initialized value of a hierarchy is /0/. When creating new models where the hierarchy field has init: true, then they will automatically be ordered after the last one.

Reordering

The Tasks example shows basic reordering functionality using a hierarchy field.

For example, given 3 existing Tasks, moving 1 of those Tasks between two others:

/**
 * Set 'moveTask' hierarchy value to a position
 * between 'afterTask' and 'beforeTask'
 */
moveTask.hierarchy = afterTask.hierarchy.before(
  beforeTask.hierarchy
);

Properties

The following fields and methods are available on hierarchy values.

value

Returns the string representation of the hierarchy, for example /1/.

hasParent

Returns true if the hierarchy is nested, for example /1/2/. Whereas /1/ and /2/ alone are top-level and would return false.

parent()

Returns the parent if one exists, or null otherwise.

previous()

Returns a sibling hierarchy value immediately before this hierarchy value. For example if the hierarchy value is /4/ its previous sibling is /3/.

next()

Returns a sibling hierarchy value immediately after this hierarchy value. For example if the hierarchy value is /3/ its next sibling is /4/.

before(otherValue)

The before method is used for reordering between two other known values.

For example, if this hierarchy value is /4/, then passing a larger sibling value of /15/ results in /5/. Similarly if this hierarchy value is /3/, then passing a larger sibling value of /4/ results in /3.1/.

Each value must be a sibling of the other — in other words there is no value between /2/ and /2/4/ because these values are not on the same level.