この章では、新しいメタデータ・オブジェクトを作成し、リレーショナル構造または式にマップする方法について説明します。また、メタデータ・オブジェクト定義のXMLテンプレートへのエクスポートおよびインポート方法、オブジェクトをアナリティック・ワークスペースに関連付ける方法、およびアナリティック・ワークスペースの構築方法についても説明します。
この章では、次の項目について説明します。
OLAP Java APIでは、永続メタデータ・オブジェクトを作成できます。最上位のメタデータ・オブジェクトは、Oracle Databaseインスタンスのデータ・ディクショナリに格納されます。このAPIでは、セッション期間中のみ存在する一時的なメタデータ・オブジェクトを作成することもできます。アプリケーションでは両方のタイプのメタデータ・オブジェクトを使用して、データ・ストア内のデータを取得または使用する問合せを作成できます。
OLAP Java APIアプリケーションでメタデータ・オブジェクトを作成するには、データベース管理者がOracle Databaseインスタンスを準備しておく必要があります。DBAは、Oracle OLAPメタデータ・オブジェクトを作成できるようにデータベース内に永続および一時表領域を設定しておき、セッション・ユーザーがオブジェクトを作成および管理できる権限を付与しておく必要があります。Oracle Databaseインスタンスの準備に関する詳細は、『Oracle OLAPユーザーズ・ガイド』を参照してください。
次元メタデータ・モデルには通常、第2章「OLAP Java APIメタデータの理解」で説明されているオブジェクトが含まれます。次元メタデータ・モデルの設計に関する詳細は、『Oracle OLAPユーザーズ・ガイド』を参照してください。
次元モデルは、OLAP Java APIメタデータ・オブジェクトを作成することによって実装します。メタデータ・オブジェクトをリレーショナル・ソース・オブジェクトにマップし、アナリティック・ワークスペースを構築するには、oracle.olapi.metadata.mappingパッケージ内のクラスを使用します。メタデータのマッピングに使用するExpressionオブジェクトを指定するには、oracle.olapi.syntaxパッケージ内のクラスを使用します。アナリティック・ワークスペースまたはリレーショナル・データベース(ROLAP)編成にメタデータ・オブジェクトをデプロイするには、oracle.olapi.metadata.deploymentパッケージ内のクラスを使用します。
次に、アナリティック・ワークスペースに次元モデルをOLAP Java APIオブジェクトとして実装する基本手順を示します。
AWオブジェクト、MdmPrimaryDimensionオブジェクトおよびMdmCubeオブジェクトを作成します。
MdmPrimaryDimensionおよびMdmCubeオブジェクトをAWにデプロイします。
各MdmPrimaryDimensionに対してMdmDimensionLevel、MdmHierarchyおよびMdmAttributeオブジェクトを作成し、MdmHierarchyLevelオブジェクトを作成してMdmDimensionLevelオブジェクトをMdmHierarchyに関連付け、MdmMeasureおよび関連オブジェクトをMdmCubeオブジェクト用に作成します。
メタデータ・オブジェクトを基本データのリレーショナル・ソースにマップします。
Transactionをコミットし、データベースに永続オブジェクトを作成します。
アナリティック・ワークスペースを構築して、リレーショナル・ソースからオブジェクトにデータをロードします。
以降の項では、これらの手順について説明します。この章のサンプルは、アナリティック・ワークスペースを作成および構築するBuildAW11g.javaサンプル・プログラムを変更したものです。また、このプログラムではアナリティック・ワークスペースをXMLテンプレートにエクスポートします。
アナリティック・ワークスペースは、関連する次元オブジェクトのコンテナです。アナリティック・ワークスペースは、oracle.olapi.metadata.deploymentパッケージ内のAWクラスによって表され、MdmDatabaseSchemaによって所有されます。
例4-1では、GLOBALユーザーのMdmDatabaseSchemaを取得し、AWを作成する例を示します。MdmRootSchemaを取得する例については、第3章を参照してください。
ディメンションは、データを識別および分類する一意値のリストです。ディメンションはキューブのエッジを形成し、キューブのメジャーの値を識別します。ディメンションは、ディメンション・メンバーを分類する1つ以上のレベルを持ちます。そのメンバーをさらに分類する階層を1つ以上持つことができます。
ディメンションは、ディメンション・メンバーに関する情報を格納する属性も持ちます。属性の作成方法については、「属性の作成」を参照してください。
この項では、ディメンション、およびディメンションのレベルと階層を表すオブジェクトの作成方法について説明します。
OLAPのディメンションは、MdmPrimaryDimensionクラスによって表されます。ディメンションはMdmDatabaseSchemaが所有します。ディメンションを作成するには、MdmDatabaseSchemaのfindOrCreateTimeDimensionまたはfindOrCreateStandardDimensionメソッドを使用します。
例4-2では、CHANNEL_AWJという名前の標準的なディメンションを作成します。この例では、AWPrimaryDimensionOrganizationオブジェクトを作成し、ディメンションをアナリティック・ワークスペースにデプロイします。mdmDBSchemaおよびawオブジェクトは、例4-1で作成したものです。最後の3行では、それぞれ例4-3、例4-4および例4-8のメソッドをコールします。
例4-2 MdmStandardDimensionの作成とデプロイ
MdmStandardDimension mdmChanDim =
mdmDBSchema.findOrCreateStandardDimension("CHANNEL_AWJ");
AWPrimaryDimensionOrganization awChanDimOrg =
mdmChanDim.createAWOrganization(aw, true);
createAndMapDimensionLevels(mdmChanDim);
createAndMapHierarchies();
commit(mdmChanDim);
MdmDimensionLevelは、同じレベルにあるディメンションのメンバーを表します。通常、レベルのメンバーは、リレーショナル・ソースのディメンション表の列内に格納されます。MdmDimensionLevelは、MemberListMapによって、リレーショナル・ソースに関連付けられます。
例4-3では、CHANNEL_AWJディメンションのMdmDimensionLevelオブジェクトを2つ作成し、このディメンション・レベルをGLOBAL.CHANNEL_DIM表のキー列にマップします。この例ではまた、ディメンション・レベルの詳細な説明属性を、この表の列にマップします。詳細な説明属性chanLongDescAttrは、例4-5で作成します。
例4-3 MdmDimensionLevelの作成とマッピング
private ArrayList<MdmDimensionLevel> dimLevelList = new ArrayList();
private ArrayList<String> dimLevelNames = new ArrayList();
private ArrayList<String> keyColumns = new ArrayList();
private ArrayList<String> lDescColNames = new ArrayList();
private void createAndMapDimensionLevels(MdmPrimaryDimension mdmChanDim)
{
dimLevelNames.add("TOTAL_CHANNEL");
dimLevelNames.add("CHANNEL");
keyColumns.add("GLOBAL.CHANNEL_DIM.TOTAL_ID");
keyColumns.add("GLOBAL.CHANNEL_DIM.CHANNEL_ID");
lDescColNames.add("GLOBAL.CHANNEL_DIM.TOTAL_DSC");
lDescColNames.add("GLOBAL.CHANNEL_DIM.CHANNEL_DSC");
// Create the MdmDimensionLevel and MemberListMap objects.
int i = 0;
for(String dimLevelName : dimLevelNames)
{
MdmDimensionLevel mdmDimLevel =
mdmChanDim.findOrCreateDimensionLevel(dimLevelNames.get(i));
dimLevelList.add(mdmDimLevel);
// Create a MemberListMap for the dimension level.
MemberListMap mdmDimLevelMemListMap =
mdmDimLevel.findOrCreateMemberListMap();
ColumnExpression keyColExp = (ColumnExpression)
SyntaxObject.fromSyntax(keyColumns.get(i),
metadataProvider);
mdmDimLevelMemListMap.setKeyExpression(keyColExp);
mdmDimLevelMemListMap.setQuery(keyColExp.getQuery());
// Create an attribute map for the Long Description attribute.
AttributeMap attrMapLong =
mdmDimLevelMemListMap.findOrCreateAttributeMap(chanLongDescAttr);
// Create an expression for the attribute map.
Expression lDescColExp = (Expression)
SyntaxObject.fromSyntax(lDescColNames.get(i),
metadataProvider);
attrMapLong.setExpression(lDescColExp);
i++;
}
}
MdmHierarchyは、次元オブジェクト・モデルの階層を表します。MdmHierarchyは、MdmLevelHierarchyまたはMdmValueHierarchyクラスのインスタンスになる場合があります。MdmLevelHierarchyは、MdmDimensionLevelオブジェクトを階層に関連付けるMdmHierarchyLevelオブジェクトの順序付けリストを持ちます。
例4-4では、CHANNEL_AWJディメンションの階層を作成します。この例では階層の階層レベルを作成し、その階層レベルに属性を関連付けます。また、階層レベルおよび属性をリレーショナル・ソースにマップします。この例では、例4-3のArrayListオブジェクトが使用されます。これによって、MdmDimensionLevelオブジェクトがマップされた同じリレーショナル・ソース・オブジェクトにMdmHierarchyLevelオブジェクトがマップされます。
例4-4 MdmLevelHierarchyおよびMdmHierarchyLevelオブジェクトの作成とマッピング
private void createAndMapHierarchies()
{
MdmLevelHierarchy mdmLevelHier =
mdmChanDim.findOrCreateLevelHierarchy("CHANNEL_PRIMARY");
// Create the MdmHierarchyLevel and HierarchyLevelMap objects.
int i = 0;
for(String hierLevelName : dimLevelNames)
{
MdmHierarchyLevel mdmHierLevel =
mdmLevelHier.findOrCreateHierarchyLevel(mdmLevelHier.getPrimaryDimension()
.findOrCreateDimensionLevel(dimLevelName));
HierarchyLevelMap hierLevelMap =
mdmHierLevel.findOrCreateHierarchyLevelMap();
ColumnExpression keyColExp = (ColumnExpression)
SyntaxObject.fromSyntax(keyColumns.get(i),
metadataProvider);
hierLevelMap.setKeyExpression(keyColExp);
hierLevelMap.setQuery(keyColExp.getQuery());
//Set the MdmDimensionLevel for the MdmHierarchyLevel.
mdmHierLevel.setDimensionLevel(dimLevelList.get(i));
i++;
}
}
属性には、ディメンション・メンバーに関する情報が格納されます。MdmBaseAttributeは、リレーショナル・ソース表に基づく値を表します。MdmDerivedAttributeは、ディメンション・メンバーの特性または関係からOracle OLAPが導出する値を表します。たとえば、MdmPrimaryDimensionのgetParentAttribute()は、各ディメンション・メンバーの親を記録するMdmDerivedAttributeを戻します。
ディメンションの基本属性は、findOrCreateBaseAttributeメソッドを使用して作成します。属性のデータ型は開発者が指定します。一部の属性については、setValueDescriptionAttributeなどのディメンションのメソッドを使用して可視化します。
例4-5では、CHANNEL_AWJディメンションの詳細な説明属性を作成し、ディメンション上で可視化します。
例4-5 MdmBaseAttributeの作成
private MdmBaseAttribute chanLongDescAttr = null;
private void createLongDesciptionAttribute(MdmPrimaryDimension mdmChanDim)
{
// Create the long description attribute and set the data type for it.
chanLongDescAttr = mdmChanDim.findOrCreateBaseAttribute("LONG_DESCRIPTION");
SQLDataType sdtVC2 = new SQLDataType("VARCHAR2");
chanLongDescAttr.setSQLDataType(sdtVC2);
// Make the attribute visible on the dimension.
mdmChanDim.setValueDescriptionAttribute(chanLongDescAttr);
属性は、ディメンションの異なるレベルのメンバーごとに、異なる値を格納できます。この場合、属性は各レベルの属性マッピングを持ちます。例4-3では、各ディメンション・レベルのMemberListMapのfindOrCreateAttributeMapメソッドをコールして、各ディメンション・レベルについて詳細な説明属性のAttributeMapを作成します。この例では、各属性マップに対して異なる列を指定します。
次元オブジェクト・モデルのキューブは、MdmCubeクラスによって表されます。MdmCubeは、1つ以上のMdmMeasureオブジェクトを所有し、メジャーをディメンション化するMdmPrimaryDimensionオブジェクトのリストを持ちます。
MdmCubeには、次のオブジェクトが関連付けられます。
MdmPrimaryDimensionオブジェクト: キューブの次元性を指定します。
MdmMeasureオブジェクト: ディメンションによって識別されるデータを格納します。
1つのCubeOrganizationオブジェクト: メジャー・データをキューブが格納および管理する方法を指定します。
CubeMapオブジェクト: キューブをリレーショナル・ソースに関連付けます。
1つのConsistentSolveSpecificationオブジェクト: 集計レベル・データを計算または解決する方法を指定します。
この節では、キューブ、およびキューブに関連付けられるいくつかのオブジェクトを作成する例を示します。例4-6では、PRICE_CUBE_AWJという名前のMdmCubeを作成します。この例では、AWCubeOrganizationオブジェクトを作成し、アナリティック・ワークスペースにキューブをデプロイします。mdmDBSchemaおよびawオブジェクトは例4-1で作成したもの、leafLevel ArrayListは例4-4で作成したものです。mdmTimeDimおよびmdmProdDimオブジェクトは、期間および製品カテゴリのディメンションです。これらのディメンションは、BuildAW11gプログラムで作成されます。例の最後の2行では、それぞれ例4-7および例4-8のメソッドをコールします。
例4-6 MdmCubeの作成とマッピング
private MdmCube createAndMapCube(MdmPrimaryDimension mdmTimeDim,
MdmPrimaryDimension mdmProdDim)
{
MdmCube mdmPriceCube = mdmDBSchema.findOrCreateCube("PRICE_CUBE_AWJ");
// Add dimensions to the cube.
mdmPriceCube.addDimension(mdmTimeDim);
mdmPriceCube.addDimension(mdmProdDim);
AWCubeOrganization awCubeOrg = mdmPriceCube.createAWOrganization(aw, true);
awCubeOrg.setMVOption(AWCubeOrganization.NONE_MV_OPTION);
awCubeOrg.setMeasureStorage(AWCubeOrganization.SHARED_MEASURE_STORAGE);
awCubeOrg.setCubeStorageType("NUMBER");
AggregationCommand aggCommand = new AggregationCommand("AVG");
ArrayList<ConsistentSolveCommand> solveCommands = new ArrayList();
solveCommands.add(aggCommand);
ConsistentSolveSpecification conSolveSpec =
new ConsistentSolveSpecification(solveCommands);
mdmPriceCube.setConsistentSolveSpecification(conSolveSpec);
// Create and map the measures of the cube.
createAndMapMeasures(mdmPriceCube);
// Commit the Transaction.
commit(mdmPriceCube);
}
この項では、キューブのメジャーを作成し、そのメジャーをリレーショナル・データベースのファクト表にマップする例を示します。この例では、例4-6で作成したキューブを使用します。
例4-7 メジャーの作成とマッピング
private void createAndMapMeasures(MdmCube mdmPriceCube)
{
ArrayList<MdmBaseMeasure> measures = new ArrayList();
MdmBaseMeasure mdmCostMeasure =
mdmPriceCube.findOrCreateBaseMeasure("UNIT_COST");
MdmBaseMeasure mdmPriceMeasure =
mdmPriceCube.findOrCreateBaseMeasure("UNIT_PRICE");
SQLDataType sdt = new SQLDataType("NUMBER");
mdmCostMeasure.setSQLDataType(sdt);
mdmPriceMeasure.setSQLDataType(sdt);
measures.add(mdmCostMeasure);
measures.add(mdmPriceMeasure);
MdmTable priceCostTable = (MdmTable)
mdmDBSchema.getTopLevelObject("PRICE_FACT");
Query cubeQuery = priceCostTable.getQuery();
ArrayList<String> measureColumns = new ArrayList();
measureColumns.add("GLOBAL.PRICE_FACT.UNIT_COST");
measureColumns.add("GLOBAL.PRICE_FACT.UNIT_PRICE");
CubeMap cubeMap = mdmPriceCube.createCubeMap();
cubeMap.setQuery(cubeQuery);
// Create MeasureMap objects for the measures of the cube and
// set the expressions for the measures. The expressions specify the
// columns of the fact table for the measures.
int i = 0;
for(MdmBaseMeasure mdmBaseMeasure : measures)
{
MeasureMap measureMap = cubeMap.findOrCreateMeasureMap(mdmBaseMeasure);
Expression expr = (Expression)
SyntaxObject.fromSyntax(measureColumns.get(i),
metadataProvider);
measureMap.setExpression(expr);
i++;
}
// Create CubeDimensionalityMap objects for the dimensions of the cube and
// set the expressions for the dimensions. The expressions specify the
// columns of the fact table for the dimensions.
ArrayList<String> factColNames = new ArrayList();
factColNames.add("GLOBAL.PRICE_FACT.MONTH_ID");
factColNames.add("GLOBAL.PRICE_FACT.ITEM_ID");
List<MdmDimensionality> mdmDimltys = mdmPriceCube.getDimensionality();
for (MdmDimensionality mdmDimlty: mdmDimltys)
{
CubeDimensionalityMap cubeDimMap =
cubeMap.findOrCreateCubeDimensionalityMap(mdmDimlty);
MdmPrimaryDimension mdmPrimDim = (MdmPrimaryDimension)
mdmDimlty.getDimension();
String columnMap = null;
if (mdmPrimDim.getName().startsWith("TIME"))
{
columnMap = factColNames.get(0);
i = 0;
}
else// (mdmPrimDim.getName().startsWith("PRODUCT"))
{
columnMap = factColNames.get(1);
i = 1;
}
Expression expr = (Expression)
SyntaxObject.fromSyntax(columnMap,
metadataProvider);
cubeDimMap.setExpression(expr);
// Associate the leaf level of the hierarchy with the cube.
MdmHierarchy mdmDefHier = mdmPrimDim.getDefaultHierarchy();
MdmLevelHierarchy mdmLevHier = (MdmLevelHierarchy)mdmDefHier;
List<MdmHierarchyLevel> levHierList = mdmLevHier.getHierarchyLevels();
// The last element in the list must be the leaf level of the hierarchy.
MdmHierarchyLevel leafLevel = levHierList.get(levHierList.size() - 1);
cubeDimMap.setMappedDimension(leafLevel);
}
}
メタデータ・オブジェクトを、データベースに永続エンティティとして保存するには、そのメタデータ・オブジェクトを作成したTransactionをコミットする必要があります。Transactionはいつでもコミットできます。Transactionをコミットするタイミングとしては、最上位レベルのオブジェクト、および最上位レベルのオブジェクトが所有するオブジェクトを作成した後をお薦めします。
例4-8では、セッションのDataProviderからTransactionProviderを取得し、現在のTransactionをコミットします。
例4-8 Transactionのコミット
private void commit(MdmSource mdmSource)
{
try
{
System.out.println("Committing the transaction for " +
mdmSource.getName() + ".");
(dp.getTransactionProvider()).commitCurrentTransaction();
}
catch (Exception ex)
{
System.out.println("Could not commit the Transaction. " + ex);
}
}
メタデータ・オブジェクトの定義を保存するには、該当オブジェクトをXMLテンプレートにエクスポートします。オブジェクトをエクスポートすると、そのオブジェクトの定義、およびそのオブジェクトが所有するすべてのオブジェクトの定義が保存されます。たとえば、AWオブジェクトをXMLにエクスポートすると、このXMLには、AWが所有するすべてのMdmPrimaryDimensionおよびMdmCubeオブジェクトの定義と、これらのディメンションおよびキューブが所有するMdmAttribute、MdmMeasureなどのオブジェクトの定義が格納されます。
例4-9では、メタデータ・オブジェクトをXMLテンプレートにエクスポートし、それをファイルに保存します。次のコードでは、exportToXMLメソッドをコールします。awオブジェクトは、例4-1で作成したアナリティック・ワークスペースです。
List objectsToExport = new ArrayList(); objectsToExport.add(aw); exportToXML(objectsToExport, "globalawj.xml");
例4-9 XMLテンプレートへのエクスポート
public void exportToXML(List objectsToExport, String fileName)
{
try
{
PrintWriter writer = new PrintWriter(new FileWriter(filename));
mp.exportFullXML(writer, // mp is the MdmMetadataProvider
objectsToExport,
null, // No Map for renaming objects
false); // Do not include the owner name
writer.close();
}
catch (IOException ie)
{
ie.printStackTrace();
}
}
メタデータ・オブジェクトの定義は、XMLテンプレートとしてインポートできます。インポート後は、オブジェクトを構築する必要があります。
メタデータ・オブジェクトを作成およびマップした後、またはオブジェクトのXML定義をインポートした後には、オブジェクトが指定する計算を実行し、結果のデータを物理記憶域構造にロードする必要があります。
例4-10では、アナリティック・ワークスペースのディメンションおよびキューブのBuildItemオブジェクトを作成します。ここでは、BuildItemオブジェクトを指定するBuildProcessを作成し、そのBuildProcessをセッションのDataProviderのexecuteBuildメソッドに渡します。
例4-10 アナリティック・ワークスペースの構築
BuildItem bldChanDim = new BuildItem(mdmChanDim);
BuildItem bldProdDim = new BuildItem(mdmProdDim);
BuildItem bldCustDim = new BuildItem(mdmCustDim);
BuildItem bldTimeDim = new BuildItem(mdmTimeDim);
BuildItem bldUnitsCube = new BuildItem(mdmUnitsCube);
BuildItem bldPriceCube = new BuildItem(mdmPriceCube);
ArrayList<BuildItem> items = new ArrayList();
items.add(bldChanDim);
items.add(bldProdDim);
items.add(bldCustDim);
items.add(bldTimeDim);
items.add(bldUnitsCube);
items.add(bldPriceCube);
BuildProcess bldProc = new BuildProcess(items);
try
{
dp.executeBuild(bldProc, 0);
}
catch (Exception ex)
{
System.out.println("Could not execute the BuildProcess." + ex);
}