Skip to main content
Previous section   Next section

Other Options

This chapter describes how to use other options for cubes and subject areas.

Also see “Accessing the Samples Shown in This Book,” in the preface.

Specifying maxFacts in the Cube Definition

While you are developing a cube, you typically recompile and rebuild it frequently. If you are using a large data set, you might want to limit the number of facts in the fact table, in order to force the cube to be rebuilt more quickly. To do this, you can specify the pMaxFacts argument for %BuildCube(); see “Building the Cube in the Terminal” in Defining Models for InterSystems Business Intelligence.

Or you can specify the maxFacts attribute as follows:

  1. In Studio, open the cube class.

  2. Find the <cube> element:

    <cube name="HoleFoods" 
    caption="HoleFoods Sales"
    defaultListing="Listing"
    nullReplacement="Missing Value"
    actionClass="HoleFoods.KPIAction"
    sourceClass="HoleFoods.Transaction">
    Copy code to clipboard
  3. Add the maxFacts attribute to this element:

    <cube name="HoleFoods" 
    caption="HoleFoods Sales"
    defaultListing="Listing"
    nullReplacement="Missing Value"
    actionClass="HoleFoods.KPIAction"
    sourceClass="HoleFoods.Transaction"
    maxFacts="10000">
    Copy code to clipboard

    The value that you specify determines the maximum size of the fact table.

  4. Save and recompile the class.

  5. Rebuild the cube.

Important:

Be sure to remove the maxFacts attribute before you deploy the cube.

Restricting the Records Used in the Cube

By default, the system uses all the records in the source class. You can modify the cube definition so that some of the records are ignored. You can do this in either or both of the following ways:

  • By specifying the Build restriction option for the cube definition, as described in “Defining Models for InterSystems Business Intelligence” in Defining Models for InterSystems Business Intelligence.

    This option has no effect if the cube is based on a data connector.

  • By defining the %OnProcessFact() callback of the cube class.

%OnProcessFact() Callback

To ignore some of the records of the base table and not include them in the cube, you can define the %OnProcessFact() method in your cube definition class:

classmethod %OnProcessFact(pID As %String, ByRef pFacts As %String,         Output pSkip As %Boolean, pInsert As %Boolean) as %Status

The system calls this method immediately after accessing each row in the base table, when building or updating the fact table. It passes the following values to this method:

  • pID is the ID of the row in the source data being processed.

  • pFacts is a multidimensional array that contains the values that will be used for the row. This array has the following structure:

    Node Value
    pFacts(factName) where factName is the name of the level or measure in the fact table, as specified by the Field name in fact table option. Value of that level or measure. For example, Magnolia or 47.
  • pInsert is 1 if this is a new row.

If you want to skip this record, your method should set pSkip to true; otherwise it should set pSkip to false.

For example, the following callback causes the cube to ignore all patients whose favorite color is blue:

ClassMethod %OnProcessFact(pID As %String, ByRef pFacts As %String, 
Output pSkip As %Boolean, pInsert As %Boolean) As %Status
{
    if pFacts("DxColor")="Blue"
    {
        set pSkip=1 
    } else {
            set pSkip=0
            }
     quit $$$OK
}
Copy code to clipboard

This example assumes that the cube defines the Field name in fact table option as DxColor for the favorite color level.

For another example, the following callback would cause the cube to ignore all records whose ID was less than 1000000:

ClassMethod %OnProcessFact(pID As %String, ByRef pFacts As %String, 
Output pSkip As %Boolean, pInsert As %Boolean) As %Status
{
    if pID<1000000
    {
        set pSkip=1 
    } else {
            set pSkip=0
            }
     quit $$$OK
}
Copy code to clipboard

Manually Specifying the Members for a Level

After you define a level in the Architect, you can manually specify the members and their order. To do so, modify the cube class in Studio as follows:

  1. In Studio, open the cube class.

  2. Find the section that defines the level:

    <level name="MyLevel" displayName="MyLevel" ... >
    </level>
    Copy code to clipboard
  3. Just before the </level> line, add a set of <member> elements like the following:

    <level name="MyLevel" displayName="MyLevel" ... >
    <member name="first" displayName="first" spec="1" />
    <member name="second" displayName="second" spec="2" />
    <member name="third" displayName="third" spec="3" />
    <member name="fourth" displayName="fourth" spec="4" />
    <member name="fifth" displayName="fifth" spec="5" />
    </level>
    Copy code to clipboard

    Each <member> element identifies a member. In <member>, name specifies the name of the member, displayName specifies an optional localized display name for the member, and spec specifies an optional key specification for this member.

    The rules for name and spec are as follows:

    Scenario Requirement Result
    Specify only name The value of name must exactly match a value of the source property or source expression, including case. The value of name becomes the key.
    Specify both name and spec The value of spec must exactly match a value of the source property or source expression, including case. The value of spec becomes the key.

    Additional notes:

    • In these attributes, you cannot use XML reserved characters. See the following subsection.

    • Include as many <member> elements as needed.

    • The order of these elements determines the default sort order of the corresponding members.

    • Include all members of the level (there is no wildcard option).

  4. Save and recompile the class.

  5. Rebuild the cube or perform a selective build of the level.

Note:

This option is useful only when the set of members is unlikely to change. If the system receives new records that contain a value not given by one of the <member> elements, those records are not represented in this level.

XML Reserved Characters

When you edit a cube class in Studio, you cannot use XML reserved characters in the values of name, displayName, or other attribute values. Instead substitute as follows:

Reserved Character Use This Instead
< &lt;
& &amp;
" &quot;
' &apos;

It is not an error to use >, but you can use &gt; instead of that character.

When you type these characters into input fields in the Architect, the Architect automatically makes these substitutions. If you examine a cube class in Studio, you might notice that the Architect also makes other substitutions. The preceding table lists only the substitutions that are necessary.

Adding Custom Indices to the Fact Table

The system automatically defines all the indices that it needs. However, you can use the fact table directly for your own purposes, and if you do, you might need additional indices. To add them, edit the cube class in Studio and add <index> elements as needed.

See “Reference Information for Cube Classes” in Defining Models for InterSystems Business Intelligence.

Customizing Other Cube Callbacks

The class %DeepSee.CubeDefinition provides callback methods that you can override to customize the cube behavior further. This section describes some commonly overridden methods.

Also see “%OnProcessFact() Callback” and “Filtering a Cube or Subject Area Dynamically,” elsewhere in this chapter.

See the class reference for %DeepSee.CubeDefinition for additional options.

%OnAfterProcessFact() Callback

The %OnAfterProcessFact() callback enables you to add custom code that runs after any given record is added or updated in the fact table of the cube.

ClassMethod %OnAfterProcessFact(pID As %String, ByRef pFactArray As %String, pUpdateStatus As %Status) as %Status

The system passes the following information to this callback:

  • pID is the id of the row in the source data being processed.

  • pFacts is an array containing the values that will be used for the row, subscripted by fact name.

  • pUpdateStatus is the status about to be returned by %ProcessFact(). If an error is passed in, this error will already be logged in the Business Intelligence logs and the ^DeepSee.BuildErrors global.

The %ProcessFact() method ignores the value returned by this method.

%OnGetDefaultListing() Callback

The %OnGetDefaultListing() callback enables you to programmatically specify the name of the listing to use, in the case where the system uses the default listing. The signature of this method is as follows:

ClassMethod %OnGetDefaultListing() as %String

This callback is called when a user requests the default listing and has no effect when a specific listing is requested. The following shows an example:

ClassMethod %OnGetDefaultListing() As %String {     Quit "Listing By Product" }

You could use this, for example, to check the role to which a user belongs and display a suitable listing for that role.

%OnExecuteListing() Callback

In some cases, additional setup work is required before a listing query can run.

To do this, implement the %OnExecuteListing() method in your cube definition class:

ClassMethod %OnExecuteListing(pSQL As %String) as %Status

The system calls this method immediately before it executes a listing query. When the system calls this method, it passes the value pSQL, which is the listing query that will be executed.

%OnAfterBuildCube() Callback

The %OnAfterBuildCube() callback, if defined, is called after the cube is built.

ClassMethod %OnAfterBuildCube(pBuildStatus As %Status, pBuildErrors As %Boolean = 0) As %Status

The system calls this as the last step in the %BuildCube method in %DeepSee.Utils. The system passes the following information to this callback:

  • buildStatus is the status of the cube build thus far

  • factErrorCount is the count of any facts for which there were build errors.

Your implementation should return an instance of %Status.

This method is called before the lock on the cube build is released, which means that only one process can execute the callback at once.

Filtering a Cube or Subject Area Dynamically

Instead of (or in addition to) specifying a hardcoded filter for a subject area, you can implement the %OnGetFilterSpec() callback. This enables you to specify the contents of the filter at runtime. This callback is also available in cube classes. Thus you can filter both cubes and subject areas dynamically.

The signature of this method is as follows:

classmethod %OnGetFilterSpec(pFilterSpec As %String) as %String

Here pFilterSpec is the value of the filterSpec attribute in <subjectArea>. The method must return a valid MDX set expression. For example:

ClassMethod %OnGetFilterSpec(pFilterSpec As %String) As %String
{
    Quit "AgeD.H1.[20 to 29]"
}
Copy code to clipboard

The following shows another simple example. In this case, the method checks the $ROLES special variable and removes any filtering if the user belongs to the %All role:

ClassMethod %OnGetFilterSpec(pFilterSpec As %String) As %String
{
    if $ROLES["%All" {
        //remove any filtering
        set pFilterSpec=""
        }
    Quit pFilterSpec

}
Copy code to clipboard

For another example, the following callback modifies the original filter value by performing a cross join of the original value and an additional filter:

ClassMethod %OnGetFilterSpec(pFilterSpec As %String) As %String
{
    //test to see if $ROLES special variable includes TestRole
    if $ROLES["%DB_SAMPLE" {
        //a member expression like the following is a simple set expression
        set colorrestrict="colord.h1.[favorite color].red"

        //create a tuple that intersects the old filter with the new filter
        //this syntax assumes original is just a member
        set newfilter="CROSSJOIN("_pFilterSpec_","_colorrestrict_")"
        set pFilterSpec=newfilter
        }
    Quit pFilterSpec

}
Copy code to clipboard