Support for AQL MATCHES and TERMINOOLGY in EhrBase?

I have been trying to run a SNOMED query via FHIR interface to Ontoserver, based on this example

select  e/ehr_id/value, 
o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/defining_code/code_string from EHR e 
contains COMPOSITION a [openEHR-EHR-COMPOSITION.externalterm.v0] 
contains OBSERVATION o [openEHR-EHR-OBSERVATION.externalterm.v0]
WHERE o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/defining_code matches [TERMINOLOGY('expand', 'hl7.org/fhir/r4', 'url=http://hl7.org/fhir/ValueSet/condition-code')]

based on this AQL sample

WHERE
    e/value/defining_code/code_string matches TERMINOLOGY('expand', 'hl7.org/fhir/r4', 'url=http://snomed.info/sct?fhir_vs=isa/50697003')

but am getting an error

{
    "error": "Bad Request",
    "message": "Could not process query/stored-query, reason: org.antlr.v4.runtime.misc.ParseCancellationException: AQL Parse exception: line 4: char 91 no viable alternative at input 'o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/defining_codematches['"
}

It looks to me as if the MATCHES clause is not supported. We know the FHIR Valueset is correct and avaiable.

Am I doing something wrong or should this be reported?

@luis_marco @stefanspiska

Ian, WHy the square brackets around the Terminology clause, that is exactly where the query parser complains about

Hi Theo,

Ah - good catch. I have no idea why I added those square brackets!! Might have helped if I had read the error message properly :frowning:

Many thanks

So this should work

select  e/ehr_id/value, 
o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/defining_code/code_string from EHR e 
contains COMPOSITION a [openEHR-EHR-COMPOSITION.externalterm.v0] 
contains OBSERVATION o [openEHR-EHR-OBSERVATION.externalterm.v0]
WHERE o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/defining_code matches TERMINOLOGY('expand', 'hl7.org/fhir/r4', 'url=http://hl7.org/fhir/ValueSet/condition-code')

@ian.mcnicoll
For ehrbase you might need to wrap the TERMINOLOGY statement in {

See here an example of a working AQL Query with terminology

Thanks Alex, I think that was actually what I was intending to do!! - just screwed up with my bracket style for MATCHES!

Can you explain why is this wrapping needed?
Second question, if you might know the answers: is this supported the same way in Better’s AQL?

The spec is a bit confusing here.

The matches binary operator is used in the WHERE clause. The left-hand operand is an AQL identified path. The right-hand operand is enclosed within curly braces ({} ), and may take the following forms:

and the example of using a terminology uri suggests including the curly brackets.

WHERE
   c/name/value='Current Problems' AND
   diagnosis/data/items[at0002.1]/value/defining_code matches { terminology://snomed-ct/hierarchy?rootConceptId=50043002 }

However the example of using a Terminology function does not - I’m not sure if this was deliberate?

WHERE
   c/name/value='Current Problems' AND
   p/data/items[at0002]/value/defining_code/code_string matches TERMINOLOGY('expand',  'hl7.org/fhir/4.0', 'http://snomed.info/sct?fhir_vs=isa/50697003')

I think that last example is wrong if nothing else it should be possible to combine a Terminology expansion with some other in-line term in the match

WHERE
   c/name/value='Current Problems' AND
   p/data/items[at0002]/value/defining_code/code_string matches { T 'mylovelyterm234567', TERMINOLOGY('expand',  'hl7.org/fhir/4.0', 'http://snomed.info/sct?fhir_vs=isa/50697003')}

Perhaps you are right, the description for matches may lead to interpretation:

The right-hand operand is enclosed within curly braces ({} ), and may take the following forms:

but the function-example and the grammar follows the work proposed by the AQL working group:

matchesOperand
    : SYM_LEFT_CURLY valueListItem (SYM_COMMA valueListItem)* SYM_RIGHT_CURLY
    | terminologyFunction
    | SYM_LEFT_CURLY URI SYM_RIGHT_CURLY
    ;

The idea was that {} indicates a list of (string) values, but that TERMINOLOGY function already returns a list (in most of the cases), so there is no need to re-wrap it. In any case, wrapping it will mean that the AQL engine will merge the list into the wrap-list (so a sort of flattening), which ultimately will get you a final list.

We can change the specifications to be more clear on this aspect, but can EHRbase change also the “default” syntax for such call?

I would always keep the curly brackets after the matches operator, as it is how it is defined in cADL. Removing it just because they could be redundant in an specific case (when using the TERMINOLOGY() function) will only make more difficult building parsers and serializers of AQL, just to cover that exception.

I get your point, but:

  • parsers works based on grammar, which clearly expects just the function (at this time);
  • the {} is not a parser hint, but is related to the type associated with the value of the right-operand, i.e. a list;
  • the {TERMINOLOGY(...)} it also to express a sort of type-casting, as in: the return of the function will have to be merged into a (empty) list

The last point is actually the reason we could say that all-good for now, no change is needed in the AQL engine, just some clarification in the AQL spec. But I just want to make sure we all agree on this.

1 Like