Hi Paul,
Let me start by saying Tim is absolutely correct, just wanted to elaborate on this for a sec to give a bit of background and answer some of your implicit questions as to why it works the way it does as well.
While everything in the REST API is driven of an Entity Data Model, the data IN TM1 itself is actually a multi-dimensional model. And while we query all the meta data we deal with using OData query syntax the queries for data coming from the model described by this metadata are executed using MDX. The result of such MDX query is then represented using EDM constructs so it can be 'queried' (read: represented) using OData again.
Note that this is not unique by itself, albeit I think I was the first to do this using the OData standard but OLE-DB for OLAP (ODBO) did the same using OLE-DB as the base as well it's XML equivalent, XML for Analysis a couple of years later. The big difference with those two is that neither ODBO or XMLA had a fixed schema to work with and on top of that simply flattened the space whereas I had to define the resulting structure as part of the EDM (the REST API's metadata) with the only escape being the use of open types. The Attributes property is a complex type which is an open type and as such, if we followed OData standard, could have any property but for TM1's case we used it to map to the attributes defined in TM1 (this applies to any object type that can have attributes in TM1).
In other words, executing an MDX query (against the data in the model) results in the creation of a Cellset Entity that subsequently, in the same or subsequent requests, can be queried. Using the Dimension properties clause on an (any) axes causes the set of those properties (read: attributes in TM1 speak) to be 'included' in that Cellset. If no dimension properties were specified explicitly then implicitly all attributes are presumed to be included.
Now, the bit of a mind twister in all this is perhaps that this set of attributes is used to project the attributes property of the Members property on the Tuples on the individual axes. There are no implicit attributes 'invented' here (I can see however how you reached that conclusion) as they simply wouldn't exist and in open types properties (representing attributes here) that don't exist simply never show up anywhere. In hindsight, we could/should perhaps have invented some CellsetAxis specific property representing these attributes and leave the projections of those Member's Attributes alone??? But it felt like, still does, like a nice and intuitive way retrieve that information (not in the last place inspired by ODBO which effectively has two Member classes for this one just extending the other with one extra attribute only used in Cellset results).
Quickly getting back to some of your questions/observations Paul:
- One Attribute, or all Attributes I can do, but I cannot figure out how to return two specific Attributes, eg Description and Control Budget.
Following OData specification [apart from the omitting space in this case]; $select=Attributes/Description,Attributes/ControlBudget,Attributes/Etc
However, using the Dimension Properties clause in the MDX and simply selecting Attributes on the Member in the Tuple is the preferred way;-!
- Errors you were getting when using $expand=Attributes
These were simply because Attributes is a complex type and therefore it's a regular property and not a navigation property.
- $expand=Members($expand=Element($select=Type,Attributes)) works but you get the Attributes twice
Well, that's correct, you are asking for them twice. First, because you are omitting a $select on the Member, which implies including all properties, therefore including Attributes, which however would be limited if you used a Dimension Properties clause in the query, and then you expand the element of each member for which you explicitly select ALL Attributes again (note that the Attributes of the associated Element are not influenced by the MDX query whatsoever).
Ok, hope that this helps you, and others that end up reading this, understand this topic a bit better. At the same time, I'm open to suggestions on improving this in a next version of the REST API, one that will likely be based on OData v4.01 which gives us more flexibility and freedom as well ;-).
Cheers,
------------------------------
Hubert Heijkers
------------------------------
Original Message:
Sent: Sun January 03, 2021 01:51 AM
From: Tim Ryan
Subject: Rest API MDX Query select more than one Attribute
Hi Paul,
You are doing it the right way with using dimension properties, you need to use $select
rather than $expand
to get the attributes because it is a normal property of a member and not a navigation property. You URL should look like this $expand=Members($select=Name,Attributes)
, then use MDX dimension properties to filter the ones you want.
------------------------------
Tim Ryan - Cubewise
Original Message:
Sent: Sat January 02, 2021 04:30 PM
From: Paul Simon
Subject: Rest API MDX Query select more than one Attribute
Hi all
Happy New Year.
I am trying to write a MDX Rest API Query that will just return the selected attributes. One Attribute, or all Attributes I can do, but I cannot figure out how to return two specific Attriutes, eg Description and Control Budget.
I am using PA 2.0.5 on premises.
I am executing an MDX Query using the following MDX:
SELECT
CROSSJOIN( {[N_Effective_Mth].[e_F4_Curr Year Pers] }, { [N_Version].[Curr Forecast] } ) on columns ,
NON EMPTY CROSSJOIN ( { [N_UCoA_Programme].[d_UCoA Programmes_Base_Excl_Std] }, {[N_UCoA_Account].[d_UCoA Accounts_Base_and_Top] } ) DIMENSION PROPERTIES [N_UCoA_Programme].[Control Budget] on rows
FROM N_Central WHERE ( [N_UCoA_Org_Unit].[1000TT] )
In the above the [d_UCoA ... are MDX Subsets which each give a large number of elements.
The following ODATA Query gives a result that includes just the Description Attribute. It seems to ignore the MDX which only asks for the Control Budget attribute
ExecuteMDX?$expand=Axes($expand=Hierarchies($select=UniqueName),
Tuples($expand=Members($select=Name,Attributes/Description))),
Cells($select=Ordinal,Value,FormattedValue,RuleDerived,Consolidated,Updateable)"
If I change the query to get just Control Budget (remembering to remove the space)
Tuples($expand=Members($select=Name,Attributes/ControlBudget))),
That works. Interesting as the spec applies to the whole Axis and only the Programme dimension has the Control Budget Attribute, not the Account dimension, I find that the result invents a Control budget Attribute on the Account dimension with a null value.
If I change the ODATA Query to omit '/ControlBudget'
"ExecuteMDX?$expand=Axes($expand=Hierarchies($select=UniqueName),
Tuples($expand=Members($select=Name,Attributes))),
Cells($select=Ordinal,Value,FormattedValue,RuleDerived,Consolidated,Updateable)"
The query works but regardless of the MDX, it returns every possible Attribute.
To a certain extent I can filter out the attributes that I don't want before returning the result to the client, but I am concerned about a potentially very large result set on the server as these dimensions have a lot of attributes some of which have a lot of text.
If I modify the query to have
$expand=Members($expand=Attributes)
I then get the errorSyntax error at position 86, near ")" for $expand query option: Expecting '/' after property of complex type in expand path.
This produces the same error
$expand=Members($expand=Attributes($select=Caption,Description))
Both attributes given above appear on both of the dimensions on the axis.
Is there a way around this?
Is my general approach right? Should I be running the MDX, getting a CellSet Id and then doing further queries to get the detail?
I ideally want to combine this with the following:
$expand=Members($expand=Element($select=Type))
So that I can get an indication as to whether a Member is Consolidated or Numeric (Base level)
This works
$expand=Members($expand=Element($select=Type,Attributes))
but then I get a full set of Attributes at both the Members and the Element levels. The key problem seems to be how to select Attributes.
Is this possible?
Ideally I would prefer to do it in the MDX rather than ODATA. However, it seems that the MDX cannot produce an Attribute that the ODATA does not include. However, the MDX DIMENSION PROPERTIES seems to have no effect on limiting the Atttributes in the query result.
Regards
------------------------------
Paul Simon
------------------------------
#PlanningAnalyticswithWatson