Hello,
I have a problem with the interpretation of an AQL query from the AQL documentation. In section 6.3 the path to the value of the systolic blood pressure is
/data[at0001]/events[at0006]/data[at0003]/items[at0004]/value/value
The first part until
/data[at0001]/events[at0006]/data[at0003]/items[at0004]/value
denotes a DV_QUANTITY.
Where is the additional field 'value' of the type DV_QUANTITY defined ?
The class itself defines the fields 'magnitude', 'precision', 'units', 'normal_range' and 'other_reference_ranges'. Its parent class DV_AMOUNT defines 'accurany_is_percent' and 'accuracy'. The next parent DV_QUANTIFIED defines 'magnitude_status' and again 'accuracy'. The next parent DV_ORDERED defines 'normal_status', 'normal_range' and again 'other_reference_ranges'. The two parents of DV_ORDERED are DATA_VALUE and Ordered, both define no fields.
Has this field access to be 'magnitude' instead of 'value' or am I missing something ?
Greetings
Georg
it’s a typo in the spec, should be value/magnitude
Thomas this is not a problem. The aql works as designed
The replies that seref and I gave address the issue. The vast majority of lab imports will use the generic analyte cluster.
I’m confused… are you saying the value/value path is not a typo in the spec?
Ah sorry. Yes that is incorrect.
Ian,
If you were referring to the discussion about paths and data types, i.e. how do you know if you can refer to some path inside a DvQuantity if the archetype only knows about DataValue and LOINC codes, it’s true that you can use such a path, if the real data (Element.value) happen to be a DvQuantity, but you have to be able to reliably figure this out at runtime, presumably by inferring it from the LOINC or other code - every time? In this situation the AQL processor cannot help you, because it doesn’t have any information about what lies beyond the Element.value point in the structure.
It seems to me that it would be preferable to convert data with DataValue specific archetypes, since the general case is that data are written once, read many times. In that case, you will have data that always has a typed analyte Cluster archetype (e.g. to DvQuantity, DvOrdinal etc), and and the AQL service will be able to do proper type / path checking. AQL authoring tools will also be able to work in a more obvious way (e.g. with auto-complete on paths etc).
So far I am not seeing a downside to this. I realise others have thought about it longer than I however …
- thomas
I am not sure where this fits in, anyway.
Given an AQL for the latest systolic like this:
select
o/data[at0001]/events[at0006]/data[at0003]/items[at0004]
from
composition c
contains
OBSERVATION o[openEHR-EHR-OBSERVATION.blood_pressure.v1]
order by o/data[at0001]/origin desc
limit 1
I will return a representation of an ELEMENT where the value is a DV_QUANTITY.
For this value object you might navigate further into the attributes like i.e. /value/magnitude to get the number 160.0.
{
“_type”: “ELEMENT”,
“archetype_node_id”: “at0004”,
“name”: {
“value”: “Systolisk”
},
“value”: {
“_type”: “DV_QUANTITY”,
“magnitude”: 160.0,
“units”: “mm[Hg]”
}
}
Hi Tom,
See comments inline please.
Ian,
If you were referring to the discussion about paths and data types, i.e. how do you know if you can refer to some path inside a DvQuantity if the archetype only knows about DataValue and LOINC codes, it’s true that you can use such a path, if the real data (Element.value) happen to be a DvQuantity, but you have to be able to reliably figure this out at runtime, presumably by inferring it from the LOINC or other code - every time? In this situation the AQL processor cannot help you, because it doesn’t have any information about what lies beyond the Element.value point in the structure.
As I mentioned in my response earlier, the serialisation of Element.value would have either xsi:type (xml) or “_type” (json) letting the consumer of the query process this information during runtime. You’re right about the aql processor not having much capability here, though this particular case is not necessarily problematic since you’ll have the archetype node id and all data instances with that arch. nd. id will be of the same type. A situation in which you’d need the aql processor to be smarter, but it cannot be is if you used this Element.value with an operator that is valid for particular types, such as ‘<’. So if you were to attempt to filter the data with aql and used Element.value to filter say based on dates such as:
“…WHERE c/bla/../item[at0022]/value/value < ‘2008-02-03’”
this would require the AQL processor to do what you said, i.e. check actual data type at runtime to make sure that Element.value is of type to which comparison operator can be applied. Heath and I just discussed this issue based on a feedback/question we received. I am currently in favour of allowing a cast at the aql level via use of a CAST function, as various SQL variants do. After all, based on the model the author of the query knows that the path will contain a date. Read on for why I would not do what you’re suggesting
It seems to me that it would be preferable to convert data with DataValue specific archetypes, since the general case is that data are written once, read many times. In that case, you will have data that always has a typed analyte Cluster archetype (e.g. to DvQuantity, DvOrdinal etc), and and the AQL service will be able to do proper type / path checking. AQL authoring tools will also be able to work in a more obvious way (e.g. with auto-complete on paths etc).
So far I am not seeing a downside to this. I realise others have thought about it longer than I however …
The downside is us, techies pushing our concern into modelling space. Very much in the spirit of python seeing huge adoption over say Scala or Haskell or even Java amongst scientists, I’d try to give clinical modellers some space here. They would have to have a grasp of the type system arguments above to see the justification for the (modelling) specialisation approach, which I think is a weak argument here. My preferred compromise is to let Aql engines know what to expect in advance using CAST (as a function, not as a keyword) and let clinical modellers go on as things are a.t.m.
All the best
Seref