View source | Discuss this page | Page history | Printable version   

Modules:Analytics ParentChild

Contents

Mapping time/date columns in Mondrian

Time/date columns deserve a special mapping in analytics. This because often you want to analyze information for a year, a quarter, a month or a set of these dimensional members.

Mondrian provides a specific way of mapping time dimensions, this to support year, quarter, month levels. See the Mondrian documentation for more information.

Openbravo supports two distinct ways of mapping time/date columns to a time dimension:

Time Member Table (preferred)

This approach uses the time member table, with a specific column, when generating the Mondrian mapping, for each date/time column, Openbravo will check if there is a special column referring to the time dimension table. If there is such a column then Openbravo will use this column and the referred time dimension to create a special Mondrian time dimension.


Client analytics time column example.png


Results in the following Mondrian mapping:

 
<Dimension name="salesOrder-orderDate" type="TimeDimension" caption="Sales Order - Order Date" foreignKey="c_order_id">
  <Hierarchy hasAll="true" primaryKey="c_order_id" primaryKeyTable="c_order">
    <Join leftKey="em_obanaly_dateordered" rightKey="obanaly_time_dimension_id" rightAlias="alias1_24">
      <Table name="c_order" alias="alias1_23">
        <SQL>alias1_23.ad_org_id in ('E443A31992CB4635AFCAEABE7183CE85','0','DC206C91AA6A4897B44DA897936E0EC3','7BABA5FF80494CAFA54DEBD22EC46F01',
'BAE22373FEBE4CCCA24517E23F0C8A48','19404EAD144C49A0AF37D54377CF452D','B843C30461EA4501935CB1D125C9C25A','2E60544D37534C0B89E765FE29BC0B43')</SQL>
      </Table>
      <Table name="obanaly_time_dimension" alias="alias1_24"/>
    </Join>
    <Level name="Year" table="alias1_24" column="theyear" uniqueMembers="true" levelType="TimeYears" type="Numeric"/>
    <Level name="Quarter" table="alias1_24" column="quarter" uniqueMembers="false" levelType="TimeQuarters" type="Numeric"/>
    <Level name="Month" table="alias1_24" column="month_of_year" uniqueMembers="false" levelType="TimeMonths" type="Numeric"/>
    <Level name="Day" table="alias1_24" column="day_of_month" ordinalColumn="yyyymmdd" uniqueMembers="false" levelType="TimeDays" type="Numeric"/>
  </Hierarchy>
</Dimension>

Openbravo will automatically update the time dimension foreign key columns using a separate process. See the configuration section in this wiki page for more information.

It is better to use the TimeDimension reference than the next provided solution (DB functions). The time dimension table:

Translate Date(Time) column to a Member with hierarchies using DB Functions

This approach uses database functions to translate a date/time column to year, quarter and month, this is done automatically by Openbravo, see here for an example of a generated mapping:

 
<Dimension name="salesOrder-accountingDate" caption="Sales Order - Accounting Date" foreignKey="c_order_id">
  <Hierarchy hasAll="true" primaryKey="c_order_id" primaryKeyTable="c_order">
    <Table name="c_order" alias="alias1_12"/>
    <Level name="Year" table="alias1_12" column="dateacct" uniqueMembers="true" levelType="TimeYears" type="Numeric">
      <KeyExpression>
        <SQL>extract(year from alias1_12.dateacct)</SQL>
      </KeyExpression>
    </Level>
    <Level name="quarter" column="dateacct" table="alias1_12" uniqueMembers="false" levelType="TimeQuarters" type="Numeric">
      <KeyExpression>
        <SQL>extract(quarter from alias1_12.dateacct)</SQL>
      </KeyExpression>
    </Level>
    <Level name="month" table="alias1_12" column="dateacct" uniqueMembers="false" type="Numeric" levelType="TimeMonths">
      <KeyExpression>
        <SQL>extract(month from alias1_12.dateacct)</SQL>
      </KeyExpression>
    </Level>
    <Level name="day" table="alias1_12" column="dateacct" ordinalColumn="dateacct" uniqueMembers="false" type="Numeric" levelType="TimeDays">
      <KeyExpression>
        <SQL>extract(day from alias1_12.dateacct)</SQL>
      </KeyExpression>
    </Level>
  </Hierarchy>
</Dimension>

Parent - Child Relations and mapping to Mondrian

Parent - child hierarchies are important for analytics as it is allows aggregation of measures accross business hierarchies.

Openbravo allows defining hierarchical structures through the standard Openbravo tree concept.

In core Openbravo the following entities can be organized in tree structures:


Client analytics tree.png


Within Mondrian it is possible to explicitly model parent - child hierarchies.

Openbravo Analytics uses the Openbravo tree structures and maps these structures to Mondrian in a generic way. This is for example visualized in the generic OB Analytics view shown below.


Client analytics tree example.png


Aggregating information across multi-level parent-child hierarchies can be a performance intensive operation. To optimize this, Mondrian has the concept of closure tables. Openbravo Analytics implements the Mondrian closure tables through its own Tree Closure table. This table is automatically updated when the Openbravo tree table is updated.

Updating parent-child information

Parent-child information is stored in a separate analytics table and columns (see next sections). These tables/columns need to be updated whenever the parent-child relations change in the business master data. To do this run the process as described here.

Parent-Child Relations: use explicit Parent/Ordinal Columns

Mondrian supports the so-called closure table to aggregate data over parent - child hierarchies. However we have noticed that the closure table implementation of Mondrian is unstable. Therefore the advice is to always create an explicit parent-ordinal column pair as is described in this section.

Also when doing direct sql querying it is however better (from a performance perspective) to have a direct parent column in the entity table. Openbravo supports this through the special parent id column. When building the closure table, Openbravo will detect if the entity has a 'obanalyTreeparentid' column/property. This is a column with a name which ends with 'obanalyTreeparentid'. If the entity has such a column then this column will be updated with the parent id determined from the tree and this parent column will be used in the Mondrian mapping. For keeping track of the ordinal (the order in the tree) you should also create a column ending on 'obanalyTreeordinal'.

So to make use of trees in OB Analytics one should take the following actions:

Also, after creating the columns then rerun the update tree and time dimension process.

Client analytics tree parent id.png

Ordering in Parent-Child: the Ordinal Column

Entities which are not part of a parent - child tree will be ordered within their level using their first identifier column.

If an entity is part of a parent - child tree and the level is mapped using this tree (in case it is not a snowflake mapping, see the limitations chapter below), then the ordering within the tree is being used. The Openbravo - Mondrian integration will try to maintain the ordering defined in the tree (when adding an instance to a tree, using drag and drop). This tree order is stored witin the entity record itself using a column with a pre-defined name. To maintain the ordering in the entity tree the table/entity needs to have a column with a name which ends with the following string: obanalyTreeordinal. The analytics module will automatically update this tree ordinal column when a change is detected in the ad_tree table.


Client analytics treeorder.png

Retrieved from "http://wiki.openbravo.com/wiki/Modules:Analytics_ParentChild"

This page has been accessed 4,146 times. This page was last modified on 7 September 2015, at 11:17. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.