While incorporating the work mentioned above, I encounter the following problem: few operations will return a boolean value, like the ‘validate’ or ‘subsumes’ operations, which takes (conceptually) an input argument.
My question is how do you suppose to use these inside AQL. How can you ‘inject’ such an argument into the function call? Is it supposed to be use in relation with a code from a data instance? In other word, is the intention to have something like:
SELECT ...
FROM ...
WHERE
TERMINOLOGY('subsumes', 'http://hl7.org/fhir/r4', CONCAT('system=http://snomed.info/sct&codeA=235856003&codeB=', e/value/defining_code/code_string))
I’m not sure who implemented already anything like this. Perhaps @heath.frankel has some suggestions/comments?
Well if you think about it, it’s like calling a terminology service component (doesn’t have to be a full service) - so the question is: what is the interface of that component? Which would give us the functions and types for TERMINOLOGY(...) calls.
I assumed the function signature and return type were already analyzed and discussed in the terminology-group meetings, the outcome being the document Terminology Server Invocation in AQL (SEC proposal). Looking to SM specs you mentioned, in relation with group proposals above, I see some good overlap:
I_TERMINOLOGY_SERVICE.value_set_validate(terminology_id, value_set_id, candidate_code) is conceptually related to TERMINOLOGY('validate', terminology, set+code)
I_TERMINOLOGY_SERVICE.subsumes(terminology_id, ref_code, candidate_child_code) is conceptually related to TERMINOLOGY('subsumes', terminology, codeA+codeB)
I_TERMINOLOGY_SERVICE.get_term(terminology_id, code, attributes) is conceptually related to TERMINOLOGY('lookup', terminology, code+property)
I_TERMINOLOGY_SERVICE.get_value_set(terminology_id, value_set_code) is conceptually related to TERMINOLOGY('expand', terminology, set)
So that mapping exercise you mention above is doable.
However, my question is more focused on AQL definition and use of this function. If it returns a set or a code, it could be used with a matches operator, like the group also mentioned in the doc above. But, if it is returning boolean (like for ‘subsumes’, ‘validate’) it actually expected also data item code as input arguments, and matches is not applicable anymore. In my opinion the WHERE clause will look like (conceptualy):
SELECT ...
FROM ... CONTAINS ... c
WHERE
TERMINOLOGY('subsumes', '...', 'system=...&codeA=...&codeB=[dataCode]')
where dataCode is a code from an identified path, e.g. c/value/defining_code/code_string
So my questions are:
is my reasoning good (on calling this function without matches opperator)?
how do you want to ‘inject’ the code there (pass the code as argument)?
I gave perhaps a silly solution above, using CONCAT(), but I have no clue what are the others thoughts on this, especially for those having a real AQL engine, like @matijap, @Seref or @heath.frankel , @birger.haarbrandt or @pablo, @bna. I need this feedback to continue on this JIRA issue.
I could change these names. Although ‘lookup()’ sounds a bit general - one could look up various things, eventually. As long as we have a clean mapping. I think for now the main thing is to agree what the functions formally do, return types etc. The spec I put up is a work in progress.
So, …9d later, any thoughts on how will this terminology function be called when it has to return a Boolean, such as when operation is 'subsumes' or 'validate'?
SELECT ...
FROM ... CONTAINS ... c
WHERE
TERMINOLOGY('subsumes', '...', 'system=...&codeA=...&codeB=[dataCode]')
The .. WHERE path matches {...} won’t work here, as the call variant of the function presumably tries to validate persisted data values against remote terminology. Somehow we need to ‘inject’ a data value (identified path) as an argument or part of 3rd argument to this function. Am I missing something?
My solution would be use of nested functions and call CONCAT():
SELECT ...
FROM ...
WHERE
TERMINOLOGY('subsumes', 'http://hl7.org/fhir/r4', CONCAT('system=http://snomed.info/sct&codeA=235856003&codeB=', e/value/defining_code/code_string))