Oracle9i OLAP Services Developer's Guide to the Oracle OLAP API
Release 1 (9.0.1)

Part Number A88756-01
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table of Contents
Contents
Go To Index
Index

Master Index

Feedback

Go to previous page Go to beginning of chapter Go to next page

Selecting Data, 5 of 5


Selecting Elements Based on Hierarchical Position

Primary Source objects that you use to navigate a hierarchy

To navigate with a hierarchy you need to create two primary Source objects: a primary Source that corresponds to the hierarchy, and a primary Source that represents the parent-child relationships within this hierarchy.

Creating a primary Source that represents a default hierarchy

To do create a primary Source that represents a default hierarchy, you take the following steps:

  1. Retrieve the default hierarchy of the MdmDimension by taking the following steps:

    1. Check to see if the MdmDimension is a union dimension by checking to see if it has an MdmUnionDimensionDefinition.

    2. If the MdmDimension has an MdmUnionDimensionDefinition, then check to see if it has a regions that are MdmHierarchy objects.

    3. If the MdmDimension has regions that are MdmHierarchy objects, select the MdmHierarchy that is its default hierarchy.

  2. Make the default hierarchy a Source object, by calling the getSource method on it.

Sample code: Retrieving a default hierarchy

The getMyDefaultHierarchy retrieves the default hierarchy of an MdmDimension is shown below. This method calls the getMyRegions method that retrieves the regions of an MdmDimension which, in turn, calls the getMyMdmUnionDimensionDefinition method that checks to see if the MdmDimension is a union dimension.

// method that gets all of the Regions of an MdmDimension
private MdmHierarchy getMyDefaultHierarchy(MdmDimension mdmDim) {
      List hierarchies = getMyRegions(mdmDim);
      if ( hierarchies == null )
        return null;
      for (Iterator iterator = hierarchies.iterator(); iterator.hasNext();) {
        MdmHierarchy hier = (MdmHierarchy) iterator.next();
        if (hier.hasMdmTag(MdmMetadataProvider.DEFAULT_HIERARCHY_TAG))
          return hier;
      }
    return null;
  }
 
// method that gets all of the Regions of an MdmDimension
private List getMyRegions(MdmDimension mdmDimension ) {
      MdmUnionDimensionDefinition unionDimDef =
   getMyMdmUnionDimensionDefinition ( mdmDimension );
      if ( unionDimDef != null )
        return unionDimDef.getMyRegions();
    return null;
  }

// method that checks to see if MdmDimension is a UnionDimension
private MdmUnionDimensionDefinition getMyMdmUnionDimensionDefinition( 
MdmDimension
      mdmDimension ) {
      MdmDimensionDefinition dimDef = mdmDimension.getDefinition();
      if((dimDef == null) || (!(dimDef instanceof MdmUnionDimensionDefinition)))
        return null;
      return (MdmUnionDimensionDefinition) dimDef;
    return null;
  }

Creating a primary Source for the parent-child relationship

If an MdmHierarchy is a level hierarchy, it's elements are in parent-child relationship to each other. To create a Source object that represents the parent-child relationships within a hierarchy, you take the following steps:

  1. Create an MdmAttribute that represents the parent-child relationships by using the getParentRelation method on the MdmHierarchy.

  2. Create a Source from the MdmAttribute created in step 1 by using the getSource method.

Creating Source objects for other relationships

A feature of the OLAP API representation of a relation, such as a parent-child relation, is that it is directional. A Source object that represents a parent-child relation maps the children to the parent, but not the parents to the children. By contrast, in SQL a table that represent thea realtionship is non-directional. The basic reason is that the OLAP API, unlike SQL, uses the structure of Source objects to automatically determine how they join. Since in the OLAP API relations are directional, if you want a relation to be in the opposite direction, you need to invert it.

Assume that there is a Source named parentChild on a hierarchy named levelHierarchy. To create Source objects that represent other relationships, you join these two Source objects in different ways. In other words, as shown in the followng table, you can create new Source objects that represent the children, siblings, and grandparents in the hierarchy by using the join method on the Source that represents the parentCihld relation.

Code 

Description 

Source childParent = 
   levelHierarchy.join(parentChild,
   levelHierarchy.value());
 

Selects those elements of the hierarchy whose parent is the given element. 

Source siblingParent =
   levelHierarchy.join(parentChild,
   parent);
 

Selects those elements of the hierarchy whose parent is the same as the parent of the given element. 

Source grandParent =
   parentChild.join(levelHierarchy,
   parentChild);
 

Selects those elements of the hierarchy whose parents are the parents of the given element.  

Example: Drilling down

Assume that there is an MdmDimension object for which you have created a Source named productsDim. Assume also that this MdmDimension object has a default hierarchy for which you have created an MdMHierarchy called prodStdHierObj and a Source called prodHeir. You use the following code to drill down the "Trousers - Women" division of the hierarchy.

// Get the parent relation from the hierarchy
MdmAttribute prodHierParentObj = prodStdHierObj.getParentRelation();
StringSource prodHierParent = prodHierParentObj.getSource();
// Select children of Trousers - Women
// - Reverse the parent relation to get a children relation
Source prodHierChildren = prodHier.join(prodHierParent, prodHier.value());
// - Note the join is hidden because we only want the children of
// - Trousers - Women, and not Trousers - Women itself
Source trousersChildren = prodHierChildren.join(prodHier,
   context.getDataProvider().createConstantSource("Trousers - Women"), false);
// Select Shirts - Boys, Trousers - Women, and Shorts - Men
Source prodHierSel = prodHier.selectValues(new String[]
  {"Shirts - Boys","Trousers - Women","Shorts - Men"});
// Insert the children of Trousers - Women after Trousers - Women
// (which is 2nd value)
Source drilledProdHierSel = prodHierSel.appendValues(trousersChildren);
// This selection has the effect of sorting the result in hierarchical order.
Source result = prodHier.selectValues(drilledProdHierSel);

Creating a Source with duplicate inputs

Suppose we want to do a region-to-region comparison in some way. Specifically, suppose we want to create a data view in which the regions appear on both the rows and the columns. In the OLAP API you use the alias() and the value() methods to do this. The alias() method creates a new Source that mirrors exactly the original Source in terms of its data, its inputs, and its outputs. The only difference is that the original Source becomes the type of the alias Source. The value() method creates a new Source that has the original Source as both its type and as an input.

Technique for creating duplicate inputs

Assume that there would naturally be an input-output match between input A of the original Source (called base) and some output B of the joined Source in the join shown below.

Source result = base.join(joined, comparison);

To avoid this input-output match, and hence keep A as an input of the result, use the following procedure.

//Create an alias for B called B2; 
Source B2 = B.alias();
//Create a variant of the original called base2
//We know that input A will match to B
Source base2 = base.join(B, B2.value());
//Now join base2 and joined
//We know that input B2 will not match to B in joined
Source preResult = base2.join(joined, comparison);
//Finally, join to the B2 and regain the input A
Source result = preResult.join(B2, A.value());

Example: Creating a Source with duplicate inputs or outputs

Assume that we have a Source named region that does not have any inputs or outputs and whose elements are the names of geographical regions. Assume also that we want to create a data view in which the regions appear on both the rows and the columns. For each cell in this table we want to show the percentage difference between the areas (in square miles) of the regions. In other words, we want to create a Source named regionComparison that has two inputs -- both of them the Source named regions.

The following code shows how you do this.

//Create an alias for region that is for the row
Source rowRegion = region.alias();
//Create an alias for region that is for the column
Source columnRegion = region.alias();
//Create rowRegionArea which has an input of rowRegion, 
//     an output of area, 
//     and elements whose values are the same as those of region
Source rowRegionArea = area.join(rowRegion.value());
//Create columnRegionArea which has an input of columnRegion, 
//     an output of area, 
//     and elements whose values are the same as those of region
Source columnRegionArea = area.join(columnRegion.value());
//Compute the values of the cells
Source areaComparison = rowRegionArea.div(columnRegionArea).times(100);
//Create a new Source with outputs rather than inputs
Source regionComparison = areaComparison.join(rowRegion.join(columnRegion))

The first two lines of code create two new Source objects that are aliases for the Source named region. These Source objects are called rowRegion and columnRegion.

The next two lines of code create Source objects, named rowRegionArea and columnRegionArea, that represent the areas of rowRegion and columnRegion respectively. To create rowRegionArea, we join area which has the input of region to rowRegion.value() which has an input of rowRegion and the same elements as region. The rowRegionArea Source has an input of rowRegion, an output of area, and elements whose values are the same as those of region. To create columnRegionArea, we join area which has the input of region to columnRegion.value() which has an input of columnRegion and the same elements as region. The Source named columnRegionArea has an input of columnRegion, an output of area, and elements whose values are the same as those of region. These join calls have the effect of replacing the region input with rowRegion or columnRegion, which, since they both have the names as regions as data, makes no real difference to the value of area.

The next line of code performs the needed computation. Because rowRegionArea has rowRegion as an input and columnRegionArea has columnRegion as an area, the new Source named areaComparison has two inputs, rowRegion and columnRegion, both of whose elements are the names of regions. What we have done is to effectively create a Source object that has duplicate inputs.

The final step of changing inputs to outputs is easy. We merely join areaComparison to its inputs (rowRegion and columnRegion).


Go to previous page Go to beginning of chapter Go to next page
Oracle
Copyright © 1996-2001, Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Book List
Go To Table of Contents
Contents
Go To Index
Index

Master Index

Feedback