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
------------------------------