Stream: cql
Topic: cql with statement
Vasyl Herman (Jun 05 2021 at 09:37):
Hi, folks! Could you please explain what the with
means in this example:
define "Outpatient Encounters with Advanced Illness":
( [Encounter: "Outpatient"]
union [Encounter: "Nonacute Inpatient"] ) OutpatientEncounter
with [Condition: "Advanced Illness"] AdvancedIllnessDiagnosis
such that exists (
OutpatientEncounter.diagnosis.condition EncounterDiagnosis
where EndsWith(EncounterDiagnosis.reference, AdvancedIllnessDiagnosis.id)
)
and OutpatientEncounter.period starts 2 years or less on or before
end of "Measurement Period"
I can't get what with [Condition: "Advanced Illness"] AdvancedIllnessDiagnosis
means.
Thanks!
Michael Riley (Jun 07 2021 at 13:32):
With clause is making the return type a list of TUPLES where the tuple is every A and B set together where the criteria fires. So this is every encounter tested against every condition.
The first clause is a standard reference check in fhir. It's checking if the reference string "EndsWith" the id of the Condition. because the format of references are like "Condition/12345".
The 2nd criteria Is referencing an external definition but it's basically doing a time-check.
So this is a time check for encounters that happened 2 years or less from Measurement Period, but we are also including the condition related to the encounter in the result.
Michael Riley (Jun 07 2021 at 14:56):
The way to read this as a series of blocks is
Definition Header
define "Outpatient Encounters with Advanced Illness":
Retrievals
( [Encounter: "Outpatient"]
union [Encounter: "Nonacute Inpatient"] ) OutpatientEncounter
with [Condition: "Advanced Illness"] AdvancedIllnessDiagnosis
Filters/Criteria
such that exists (
OutpatientEncounter.diagnosis.condition EncounterDiagnosis
where EndsWith(EncounterDiagnosis.reference, AdvancedIllnessDiagnosis.id)
)
and OutpatientEncounter.period starts 2 years or less on or before
end of "Measurement Period"
Vasyl Herman (Jun 07 2021 at 15:03):
Michael, I appreciate it ! It's very clear now!
Is there a documentation somewhere about it?
Thanks!
John Silva (Jun 07 2021 at 15:06):
JP (Jun 07 2021 at 15:07):
Specifically - https://cql.hl7.org/02-authorsguide.html#relationships
Michael Riley (Jun 07 2021 at 15:44):
@JP I have never seen the FHIR cql library properly enforce relationships through the with clause, hence why we need to use filter clauses like this to link them. I'm sure other QDM models do, but is this functionality in cql-fhir now? And if it's not, what would be needed to do so?
JP (Jun 07 2021 at 15:48):
I don't quite follow what you mean by "properly enforce relationships". Would you mind giving me an example of what you mean and what your expected behavior would be?
Michael Riley (Jun 07 2021 at 17:45):
I might be describing a personal assumption/perference, not an actual aspect of the language, so maybe I shouldn't use the word "proper", sorry.
Let's say I have Condition A B and C, and Encounters D E and F and the relationships via the field "Encounter.diagnosis.condition.reference" in the Encounter FHIR resource maps out like this.
D->A
E->B
F->C
So each Encounter is associated to a different Condition. In the retrieval block I would perfer the with
clause to only pull the tuples (A,D), (B,E), and (C,F). However I believe (haven't tested this recently) the example pulls all combinations of tuples instead: (A,D),(A,E),(A,F),(B,D),(B,E),(B,F),(C,D),(C,E),(C,F). Which is why we have to use the reference criteria block in the first place: to filter out the 6 tuples that aren't linked together.
When I'm trying to write a multi-query definition sometimes I do want to compare 2 separate sets to each other, but most often I'm actually just trying to pull DIRECTLY RELATED resources together. They're not really 2 different medical context, it's actually just the same medical context across 2 different resources. Maybe the with
clause isn't the best structure to be doing that with, but it might be helpful to have a with linked
keyword or something similar to that in the grammar because that's usually what I want to do.
Bryn Rhodes (Jun 10 2021 at 20:42):
@Michael Riley , yes, the with clause is only for cases where you are filtering by the relationship, not for cases where you actually want the data from both sources. You can still do this without using a multi-source query, using the let
clause:
define MedicationRequestAndEncounter:
[MedicationRequest] M
let E: [Encounter: id = Last(Split(M.encounter.reference, '/'))]
return { medicationRequest: M, encounter: E }
Michael Riley (Jun 15 2021 at 15:33):
@Bryn Rhodes Is that a valid retreival for FHIR resources? id is not a searchable parameter in FHIR, so you can't create a searchset from a set of ids.
Last updated: Apr 12 2022 at 19:14 UTC