Logical model describes the data from user’s or analyst’s perspective: data
how they are being measured, aggregated and reported. Model is independent of
physical implementation of data. This physical independence makes it easier to
focus on data instead on ways of how to get the data in understandable form.

provide more descriptive attribute labels for display in the applications or
reports

transparent localization of metadata and data

Analysts or report writers do not have to know where name of an organisation
or category is stored, nor he does not have to care whether customer data is
stored in single table or spread across multiple tables (customer, customer
types, ...). They just ask for customer.name or category.code.

In addition to abstraction over physical model, localization abstraction is
included. When working in multi-lingual environment, only one version of
report/query has to be written, locales can be switched as desired. If
requesting “contract type name”, analyst just writes constract_type.name and
Cubes framework takes care about appropriate localisation of the value.

Example: Analysts wants to report contract amounts by geography which has two
levels: country level and region level. In original physical database, the
geography information is normalised and stored in two separate tables, one for
countries and another for regions. Analyst does not have to know where the
data are stored, he just queries for geography.country and/or
geography.region and will get the proper data. How it is done is depicted on
the following image:

Mapping from logical model to physical data.

The logical model describes dimensions geography in which default hierarchy
has two levels: country and region. Each level can have more attributes,
such as code, name, population... In our example report we are interested only
in geographical names, that is: country.name and region.name.

Cubes in a model will inherint mappings and joins from the model. The mappings
are merged in a way that cube’s mappings replace existing model’s
mappings with the same name. Joins are concatenated or merged by their name.

Example from the SQL backend: Say you would like to join a date dimension
table in dim_date to every cube. Then you specify the join at the model
level as:

The join has a name specified, which is used to match joins in the cube. Note
that the join contains incomplete information: it contains only the detail
part, that is the dimension key. To use the join in a cube which has two date
dimensions start date and end date:

The model can be represented either as a JSON file or as a directory with JSON
files. The single-file model specification is just a dictionary with model
properties. The model directory bundle should have the following content:

model.json – model’s master metadata – same as single-file model

dim_*.json – dimension metadata file – single dimension dictionary

cube_*.json – cube metadata – single cube dictionary

The list of dimensions and cubes in the model.json are merged with the
dimensions and cubes in the separate files. Avoid duplicate definitions.

Measures are numerical properties of a fact. They might be represented, for
example, as a table column. Measures are aggregated into measure aggregates.
The measure is described as:

name – measure identifier (required)

label – human readable name to be displayed (localized)

info – additional custom information (unspecified)

aggregates – list of aggregate functions that are provided for this
measure. This property is for generating default aggregates automatically.
It is highly recommended to list the aggregates explicitly and avoid using
this property.

window_size – number of elements within a window for window functions
such as moving average. If not provided and function requires it then 1 (one
element) is assumed.

If there is a list of aggregates already specified in the cube explicitly,
both lists are merged together.

Note

To prevent automated creation of default aggregates from measures, there
is an advanced cube option implicit_aggergates. Set this property to
False if you want to keep only explicit list of aggregates.

In previous version of Cubes there was omnipresent measure aggregate
called record_count. It is no longer provided by default and has to be
explicitly defined in the model. The name can be of any choice, it is not
a built-in aggregate anymore. To keep the original behavior, the following
aggregate should be added:

"aggregates":[{"name":"record_count","function":"count"}]

Note

Some aggregates do not have to be computed from measures. They might be
already provided by the data store as computed aggregate values (for
example Mixpanel’s total). In this case the measure and function
serves only for the backend or for informational purposes. Consult the
backend documentation for more information about the aggregates and
measures.

It is possible to specify how dimensions are linked to the cube. The
dimensions list might contain, besides dimension names, also a
specification how the dimension is going to be used in the cube’s context. The
specification might contain:

hierarchies – list of hierarchies that are relevant for the cube. For
example the date dimension might be defined as having day granularity,
but some cubes might be only at the month level. To specify only relevant
hierarchies use hierarchies metadata property:

exclude_hierarchies – hierarchies to be excluded when cloning the
original dimension. Use this instead of hierarchies if you would like to
preserve most of the hierarchies and remove just a few.

default_hierarchy_name – name of default hierarchy for a dimension in
the context of the cube

cardinality – cardinality of the dimension with regards to the cube. For
example one cube might contain housands product types, another might have
only a few, but they both share the same products dimension

alias – how the dimension is going to be called in the cube. For
example, you might have two date dimensions and name them start_date and
end_date using the alias

The above cube will have three dimensions: date, customer and
contract_date. The date dimension will have only two hierarchies with
lowest granularity of month, the customer dimension will be assigned as-is
and the contract_date dimension will be the same as the original date
dimension.

If you are creating more dimensions with the same or similar structure, such
as multiple dates or different types of organisational relationships, you
might create a template dimension and then use it as base for the other
dimensions:

All properties from the template dimension will be copied to the new
dimension. Properties can be redefined in the new dimension. In that case, the
old value is discarded. You might change levels, hierarchies or default
hierarchy. There is no way how to add or drop a level from the template, all
new levels have to be specified again if they are different than in the
original template dimension. However, you might want to just redefine
hierarchies to omit unnecessary levels.

Note

In mappings name of the new dimension should be used. The template
dimension was used only to create the new dimension and the connection
between the new dimension and the template is lost. In our example above,
if cube uses the creation_date and closing_date dimensions and any
mappings would be necessary, then they should be for those two dimensions,
not for the date dimension.

list of other additional attributes that are related to the level. The
attributes are not being used for aggregations, they provide
additional useful information.

key

key field of the level (customer number for customer level, region
code for region level, year-month for month level). key will be used
as a grouping field for aggregations. Key should be unique within
level.

label_attribute

name of attribute containing label to be displayed (customer name for
customer level, region name for region level, month name for month
level)

order_attribute

name of attribute that is used for sorting, default is the first
attribute (key)

cardinality

symbolic approximation of the number of level’s members

role

Level role (see below)

info

custom info, such as formatting. Not used by cubes framework.

Fields marked with * are required.

If no attributes are specified then only one attribute is assumed with the
same name as the level.

If no key is specified, then first attribute is assumed.

If no label_attribute is specified, then second attribute is assumed if
level has more than one attribute, otherwise the first attribute is used.

Dimension level attributes can be specified either as rich metadata or just
simply as strings. If only string is specified, then all attribute metadata
will have default values, label will be equal to the attribute name.

Key

Description

name

attribute name (should be unique within a dimension)

label

human readable name - can be used in an application, localizable

order

natural order of the attribute (optional), can be asc or desc

format

application specific display format information

missing_value

Value to be substituted when there is no value (NULL) in the source
(backend has to support this feature)

locales

list of locales in which the attribute values are available in
(optional)

info

custom info, such as formatting. Not used by cubes framework.

The optional order is used in aggregation browsing and reporting. If
specified, then all queries will have results sorted by this field in
specified direction. Level hierarchy is used to order ordered attributes. Only
one ordered attribute should be specified per dimension level, otherwise the
behavior is unpredictable. This natural (or default) order can be later
overridden in reports by explicitly specified another ordering direction or
attribute. Explicit order takes precedence before natural order.

For example, you might want to specify that all dates should be ordered by
default:

"attributes"=[{"name"="year","order":"asc"}]

Locales is a list of locale names. Say we have a CPV dimension (common
procurement vocabulary - EU procurement subject hierarchy) and we are
reporting in Slovak, English and Hungarian. The attributes will be therefore
specified as:

Some dimensions and levels might have special, but well known, roles. One
example of a role is time. There might be more recognized roles in the future,
for example geography.

Front-ends that respect roles might provide different user interface elements,
such as date and time pickers for selecting values of a date/time dimension.
For the date picker to work, the front-end has to know, which dimension
represents date and which levels of the dimension represent calendar units
such as year, month or day.

The role of a dimension has to be explicitly stated. Front-ends are not
required to assume a dimension named date is really a full date dimension.

The level roles do not have to be mentioned explicitly, if the level name
can be recognized to match a particuliar role. For example, in a dimension
with role time level with name year will have automatically role year.

Level roles have to be specified when level names are in different language or
for any reason don’t match english calendar unit names.