Common CQL Assets for FHIR (US-Based)
1.0.0-ballot - STU 1 Ballot
This page is part of the Common CQL Assets for FHIR (US-Based) (v1.0.0-ballot: STU 1 Ballot 1) based on FHIR (HL7® FHIR® Standard) R4. No current official version has been published yet. For a full list of available versions, see the Directory of published versions
Page standards status: Informative |
This topic provides architectural guidance for implementers supporting FHIR and CQL-based questionnaires, typically from a DTR-style application.
This discussion assumes the following:
item
elements, nested to any degreeinitialExpression
, candidateExpression
and calculatedExpression
extensions referencing CQL expressions to be evaluatedThis guidance is provided as a complement to the conformance expectations and guidance described in Pre-populating QuestionnaireResponses in the DTR implementation guide.
All data access within CQL occurs within the Retrieve expression. When CQL is packaged within a Library resource, these retrieves are surfaced as dataRequirement
elements according to the mapping defined in the Data Requirements of the Using CQL With FHIR IG. These data requirements allow the complete data expectations for the CQL within the library to be communicated. However, these elements in the Library resource represent the total data requirements for the library, whereas the Questionnaire may only reference some of the expressions in the library, or the initial state of the Questionnaire may be such that only a subset of questions are enabled and therefore need population.
To address this, static analysis of the CQL can be used to determine the set of data requirements for an expression (or set of expressions), as described in the Artifact Data Requirements section of the CQL specification. The DataRequirementsProcessor provides an implementation of this capability. This component can accept a list of the expressions that should be analyzed to determine data requirements.
Note that this process of analyzing data requirements is simplified by the practice of having all the expressions in a given questionnaire reference a single CQL library, the "primary artifact library". This approach is used in measure development and provides a way to organize content per artifact. Expressions from other libraries can still be used, but must be referenced by declaring a passthrough expression in the primary artifact library. This can be an undue burden for questionnaire authors, so this is not considered best-practice for questionnaires. However, all the examples in this implementation guide take this approach to simplify data requirements analysis processing.
In addition to gathering the effective data requirements through dependency tracing of specific expressions, data requirements can be collapsed (i.e. minimized to eliminate duplicate or overlapping requests). These techniques can be combined to ensure that applications can minimize the number of queries used to retrieve data necessary to evaluate the CQL logic within the questionnaire.
TODO: Provide guidance about making the determination between sending libraries up front versus questionnaire specific libraries (https://hl7.org/fhir/us/davinci-dtr/STU2.1/specification.html#adaptive-form-considerations)
https://hl7.org/fhir/us/davinci-dtr/STU2.1/specification.html#value-set-and-code-system-guidance
Note that questionnaires may reference value sets that are not included in the questionnaire package. In particular, best practice for value sets that do not have expansions (for example because the value set definition is more concisely expressed as a condition, or the value set is too large) is that they not be included in the questionnaire package.
Value set references will be encountered in two different ways in CQL used by a Questionnaire:
retrieve
expressions, as the terminology filterIn both cases, the required terminology will need to be made available to the CQL engine. Different approaches can be taken by different CQL engines, but in general they follow:
The first approach is somewhat simpler, though may be less performant, especially when the number and/or size of the value sets is large.
In addition, for performance, the second approach will likely be implemented with caching.
As well, depending on the sensitivity of the questions to updates in code systems, the expansion of value sets used may need to be performed with version-specific references to the code systems and value sets involved.
When questionnaires and CQL libraries reference value sets, they may do so with a version-specific, or a version-independent reference. CQL libraries often use version-independent references for value sets to minimize the maintenance overhead involved in updating value set versions. To establish the versions of value sets referenced in this way, a Version Manifest may be used if there is a need to indicate a specific version for a particular deployment.
When a value set reference appears within a retrieve
, the corresponding DataRequirement will include the value set reference. For example:
define "Glucose Tests":
[Observation: "Glucose Test Codes"]
{
"type": "Observation",
"codeFilter": [{
"path": "code",
"valueSet": "http://example.org/ValueSet/glucose-test-codes"
}]
}
This data requirement can be satisfied with an appropriate FHIR query:
[base]/Observation?subject=Patient/123&code:in=http://example.org/ValueSet/glucose-test-codes
However, use of this approach requires that the EHR's FHIR server 1) supports the :in
modifier for code-based searches, 2) either has or can get the Glucose Test Codes value set, and 3) can perform (or ask for) an appropriate expansion of the value set. To address the situation where the EHR does not or cannot support code-based searching with value sets, the query may be executed by either:
category=laboratory
in this case) (or no filter at all) and then filtering the result in the CQL[base]/Observation?subject=Patient/123&category=laboratory
[base]/Observation?subject=Patient/123&code=12345,23456,34567
Note that when in-lining large value sets, the resulting search may overflow practical URL length restrictions. In these cases, a POST may be used, and/or the query may be split into multiple requests and combined.
As with any data processing application, when processing CQL, accessing the data often takes the majority of the time. As such, ensuring performant data access is a key aspect of delivering performant applications that make use of CQL.
When retrieving the set of data required to evaluate a CQL expression, the search parameter to use may vary depending on the capabilities of the server being accessed. For example, the code
search parameter for Condition resources is optional in USCore, so systems may not support that as an access path. In these cases, applications can make use of a Module Configuration Library to provide alternative FHIR queries.
For example, given a CQL retrieve expression requesting Conditions from a particular value set:
define "Diabetes Conditions":
[Condition: "Diabetes"]
When accessing this data from a server that does not support the Condition.code
search parameter, a less-selective filter may be used initially:
[base]/Condition?category=problem-list-item
followed by subsequent filtering locally based on the "Diabetes"
value set.
In addition, multi-threading requests to the server can reduce the overall time required to retrieve the data.
As with any content development effort, to facilitate readability and maintainability of CQL, best-practice is to follow and contribute to the conventions established by the community: