diff --git a/structured-query/documentation/2021_01_29StructeredQueriesDocumentation(Draft).md b/structured-query/documentation/2021_10_18StructeredQueryV2Documentation.md similarity index 60% rename from structured-query/documentation/2021_01_29StructeredQueriesDocumentation(Draft).md rename to structured-query/documentation/2021_10_18StructeredQueryV2Documentation.md index 18e9fae..ff3d150 100644 --- a/structured-query/documentation/2021_01_29StructeredQueriesDocumentation(Draft).md +++ b/structured-query/documentation/2021_10_18StructeredQueryV2Documentation.md @@ -1,6 +1,7 @@ + # Structured Queries -CODEX front-end allows users to create feasibility queries based on inclusion and exclusion criteria. The different inclusion and exclusion criteria are conjuncted with the "AND" and "OR" operators respectively. Resulting in a conjunctive normal form (CNF) for inclusion and disjunctive normal form (DNF) for the exclusion criteria. +CODEX front-end allows users to create feasibility queries based on inclusion and exclusion criteria. The different inclusion and exclusion criteria are conjuncted with the "AND" and "OR" operators respectively. Resulting in a conjunctive normal form without negation (CNF) for inclusion and disjunctive normal form without negation (DNF) for the exclusion criteria. The front-end created queries need to be transmitted to different back-end services which translates the Structured Query format into other query formats such as FHIR Search or CQL. As common data exchange format the so called *Structured Queries* are defined. @@ -15,24 +16,24 @@ The metadata provides some basic information about the query: | Name | Description | | :-------- | -------------------------------------- | | Version | API Version | -| Timestamp | Timestamp when the query was send | +| Timestamp | Timestamp when the query was sent | | queryId | unique Id to identify a specific query | ## Query -As previously introduced the query is based on inclusion and exclusion criteria represented in CNF and DNF. +As previously introduced, the query is based on inclusion and exclusion criteria represented in CNF and DNF. -With in the query both CNF and DNF are conjuncted with an "AND NOT" operator. +With in the query, both CNF and DNF are conjunct with an "AND NOT" operator. -For the normal Form different building blocks are provided to represent the conjunctions of criteria. +For the normal form, different building blocks are provided to represent the conjunctions of criteria. ## inclusionCriteria\[][] Given a CNF: A and (B or C) -The inclusionCriteria is an array of arrays of criteria. Within the outer array all elements are conjuncted with "AND". Based on the example {A} {B or C}. +The inclusionCriteria is an array of arrays of criteria. Within the outer array, all elements are conjunct with "AND". Based on the example {A} {B or C}. -Within the inner array all elements are disjuncted with "OR". Based on the example {B}{C}. A special case is given if only one element is given e.g. {A}. In this case no logic operation is applied to this element in this hierarchic element. +Within the inner array all elements are disjunct with "OR". Based on the example {B}{C}. A special case is given if only one element is given, e.g. {A}. In this case, no logic operation is applied to this element in this hierarchic element. -> inclusionCriteria= {{A}, {B, C}} @@ -42,9 +43,9 @@ Analog for the exclusion criteria: Given a DNF: A or (B and C) -The exclusionCriteria is an array of arrays of criteria. Within the outer array all elements are disjuncted with "OR". Based on the example {A} {B and C} . +The exclusionCriteria is an array of arrays of criteria. Within the outer array, all elements are disjunct with "OR". Based on the example {A} {B and C}. -Within the inner array all elements are conjuncted with "And". Based on the example {B}{C} . A special case is given if only one element is given e.g. {A}. In this case no logic operation is applied to this element in this hierarchic element. +Within the inner array all elements are conjunct with "And". Based on the example {B}{C} . A special case is given if only one element is given, e.g. {A}. In this case, no logic operation is applied to this element in this hierarchic element. -> exclusionCriteria = {{A}, {B, C}} @@ -52,19 +53,15 @@ Within the inner array all elements are conjuncted with "And". Based on the exam The previous introduced elements {A}, {B} and {C} are representative for different criteria. -Each criterion represents a unique concept or statement which is identified by its termCode. Which can be further specified by applying a value filter. +Each criterion represents a unique concept or statement, which is identified by its termCodes. A criterion can have multiple TermCodes if they are synonymous and mapped identically. Which can be further specified by applying a value filter. ## termCode -The termCode defines a concept based on a coding system (i.e. LOINC). The triplet of code, system and version identify the concept. An additional display element allows for a human readable form (This value SHALL be the same as the value define by the coding system) +The termCode defines a concept based on a coding system (i.e. LOINC). The triplet of code, system and version identify the concept. An additional display element allows for a human-readable form (This value SHALL be the same as the value define by the coding system) ## valueFilter -ValueFilter specify the value of a defined concept. Depending on the valueFilter Type different value statements can be made. - - - - +ValueFilter specify the value of a defined concept. Depending on the valueFilter Type, different value statements can be made. The valueFilter restricts the value of the highest interest of the resource. ### quantity-comperator @@ -85,7 +82,26 @@ A valueFilter of type quantity-comperator can be applied to all numeric criterio A valueFilter of type quantity-range can be applied to all numeric criterion concepts to validate if a value is within the boundaries of the defined min and max values. Again a unit can be given. -## ConceptValueFilter +### DateTime-comperator + +A valueFilter of type datetype can be applied to all datetime criterion concepts. It allows to use the + +| Enumeration | Comparator | +| ----------- | ------------- | +| le | less equal | +| ge | greater equal | + +ISO Datum + +### DateTime-range + +A valueFilter of type datetime-range can be applied to all datetime criterion concepts to validate if a value is an overlap exists between the criterions datetime and the interval explicitly or implicitly defined by the before and/or afterDate. ISO dateformat. + +beforeDate + +afterDate + +### Concept-ValueFilter A valueFilter of type concept can be applied to all concepts which have a value which itself is defined by a concept. The Value can be restricted by selectedConcepts which are termCodes. If multiple selectedConceptsare given the criterion is fulfilled if one of the values matches. @@ -93,18 +109,18 @@ Example: The patient gender is a concept and can be represented with a Termcode. The values female, male, diverse, etc. are also concepts representable by termCodes. -"All male or female patients" (PseudoCriterion): +"All male or female patients " (PseudoCriterion): ```json { "inclusionCriteria": [ [ { - "termCode": { + "termCode": [ { "code": "LL2191-6", "display": "Geschlecht", "system": "http://loinc.org" - }, + } ], "valueFilter": { "type": "concept", "selectedConcepts": [ @@ -130,3 +146,6 @@ The patient gender is a concept and can be represented with a Termcode. The valu +## AttributeFilter[] + +Attribute Filter are valueFilter for specific attributes of the Resource. The AttributeCode defined as termCode specifies which attribute is restricted. diff --git a/structured-query/example-json/2021_02_01_QueryExampleWithoutTimeRestriction.json b/structured-query/example-json/2021_02_01_QueryExampleWithoutTimeRestriction.json deleted file mode 100644 index 389e664..0000000 --- a/structured-query/example-json/2021_02_01_QueryExampleWithoutTimeRestriction.json +++ /dev/null @@ -1,131 +0,0 @@ -{ - "version": "http://to_be_decided.com/draft-1/schema#", - "inclusionCriteria": [ - [ - { - "termCode": { - "code": "LL2191-6", - "display": "Geschlecht", - "system": "http://loinc.org" - }, - "valueFilter": { - "type": "concept", - "selectedConcepts": [ - { - "code": "F", - "display": "female", - "system": "https://fhir.loinc.org/CodeSystem/$lookup?system=http://loinc.org&code=LL2191-6", - "version": "" - }, - { - "code": "M", - "display": "male", - "system": "https://fhir.loinc.org/CodeSystem/$lookup?system=http://loinc.org&code=LL2191-6", - "version": "" - } - ] - } - } - ], - [ - { - "termCode": { - "code": "30525-0", - "display": "Alter", - "system": "http://loinc.org" - }, - "valueFilter": { - "type": "quantity-comparator", - "comparator": "gt", - "quantityUnit": { - "code": "a", - "display": "Jahr" - }, - "value": 18 - } - } - ], - [ - { - "termCode": { - "code": "F00", - "display": "F00", - "system": "http://fhir.de/CodeSystem/dimdi/icd-10-gm" - } - }, - { - "termCode": { - "code": "F09", - "display": "F09", - "system": "http://fhir.de/CodeSystem/dimdi/icd-10-gm" - } - } - ] - ], - "exclusionCriteria": [ - [ - { - "termCode": { - "code": "LL2191-6", - "display": "Geschlecht", - "system": "http://loinc.org" - }, - "valueFilter": { - "type": "concept", - "selectedConcepts": [ - { - "code": "male", - "display": "male", - "system": "", - "version": "" - } - ] - } - } - ], - [ - { - "termCode": { - "code": "30525-0", - "display": "Alter", - "system": "http://loinc.org" - }, - "valueFilter": { - "type": "quantity-comparator", - "comparator": "gt", - "quantityUnit": { - "code": "year", - "display": "Jahr" - }, - "value": 65 - } - } - ], - [ - { - "termCode": { - "code": "F00.9", - "display": "F00.9", - "system": "http://fhir.de/CodeSystem/dimdi/icd-10-gm" - } - }, - { - "termCode": { - "code": "8310-5", - "display": "Körpertemperatur", - "system": "http://loinc.org" - }, - "valueFilter": { - "type": "quantity-range", - "quantityUnit": { - "code": "Cel", - "display": "°C" - }, - "minValue": 35, - "maxValue": 39 - } - } - ] - ], - "display": "Beispiel-Query" -} diff --git a/structured-query/example-json/2021_10_18_StructuredQueryV2Example.json b/structured-query/example-json/2021_10_18_StructuredQueryV2Example.json new file mode 100644 index 0000000..cee5e3a --- /dev/null +++ b/structured-query/example-json/2021_10_18_StructuredQueryV2Example.json @@ -0,0 +1,172 @@ +{ + "version": "http://to_be_decided.com/draft-2/schema#", + "display": "Beispiel-Query", + "inclusionCriteria": [ + [ + { + "termCodes": [ + { + "code": "LL2191-6", + "display": "Geschlecht", + "system": "http://loinc.org" + } + ], + "valueFilter": { + "type": "concept", + "selectedConcepts": [ + { + "code": "F", + "display": "female", + "system": "https://fhir.loinc.org/CodeSystem/$lookup?system=http://loinc.org&code=LL2191-6", + "version": "" + }, + { + "code": "M", + "display": "male", + "system": "https://fhir.loinc.org/CodeSystem/$lookup?system=http://loinc.org&code=LL2191-6", + "version": "" + } + ] + } + } + ], + [ + { + "termCodes": [ + { + "code": "30525-0", + "display": "Alter", + "system": "http://loinc.org" + } + ], + "valueFilter": { + "type": "quantity-comparator", + "comparator": "gt", + "unit": { + "code": "a", + "display": "Jahr" + }, + "value": 18 + } + } + ], + [ + { + "termCodes": [ + { + "code": "F00", + "display": "F00", + "system": "http://fhir.de/CodeSystem/dimdi/icd-10-gm" + } + ] + }, + { + "termCodes": [ + { + "code": "F09", + "display": "F09", + "system": "http://fhir.de/CodeSystem/dimdi/icd-10-gm" + } + ], + "timeRestriction": { + "beforeDate": "2021-10-09", + "afterDate": "2021-09-09" + } + } + ] + ], + "exclusionCriteria": [ + [ + { + "termCodes": [ + { + "code": "LL2191-6", + "display": "Geschlecht", + "system": "http://loinc.org" + } + ], + "valueFilter": { + "type": "concept", + "selectedConcepts": [ + { + "code": "male", + "display": "male", + "system": "", + "version": "" + } + ] + } + } + ], + [ + { + "termCodes": [ + { + "code": "30525-0", + "display": "Alter", + "system": "http://loinc.org" + } + ], + "valueFilter": { + "type": "quantity-comparator", + "comparator": "gt", + "unit": { + "code": "year", + "display": "Jahr" + }, + "value": 65 + } + } + ], + [ + { + "termCodes": [ + { + "code": "F00.9", + "display": "F00.9", + "system": "http://fhir.de/CodeSystem/dimdi/icd-10-gm" + } + ] + }, + { + "termCodes": [ + { + "code": "8310-5", + "display": "Körpertemperatur", + "system": "http://loinc.org" + } + ], + "valueFilter": { + "type": "quantity-range", + "unit": { + "code": "Cel", + "display": "°C" + }, + "minValue": 35, + "maxValue": 39 + }, + "attributeFilters": [ + { + "attributeCode": { + "code": "method", + "system": "abide", + "display": "method" + }, + "type": "concept", + "selectedConcepts": [ + { + "code": "LA9370-3", + "system": "http://loinc.org", + "display": "Axillary" + } + ] + } + ], + "timeRestriction": { + "beforeDate": "2021-10-09", + "afterDate": "2021-09-09" + } + } + ] + ] +} diff --git a/structured-query/json-schema/2021_01_29_StructuredQuerySchema(Draft).json b/structured-query/json-schema/2021_01_29_StructuredQuerySchema(Draft).json deleted file mode 100644 index b1bda6c..0000000 --- a/structured-query/json-schema/2021_01_29_StructuredQuerySchema(Draft).json +++ /dev/null @@ -1,124 +0,0 @@ -{ - "$schema": "http://to_be_decided.com/draft-1/schema#", - - "definitions": { - - "termCode": { - "type": "object", - "description": "The termCode defines a concept based on a coding system (i.e. LOINC). The triplet of code, system and version identify the concept.", - "properties": { - "code": { "type": "string" }, - "system": { "type": "string"}, - "version": { "type": "string"}, - "display": { "type": "string"}, - }, - "required": ["code", "system", "display"], - }, - - "criterion": { - "type": "object", - "properties": { - "termCode": { "$ref": "#/definitions/termCode" }, - "valueFilter": { "$ref": "#/definitions/valueFilter"} - }, - "required": ["termCode"], - }, - - "unit": { - "type": "object", - "title": "UCUM Unit", - "description": "The unit is a ucum unit (https://ucum.org/trac)", - "properties": { - "code": { "type": "string" }, - "display": {"type": "string"} - }, - "required": ["code", "display"], - }, - - "valueFilter": { - "type": "object", - "properties": { - "type": { "enum": ["concept", "quantity-comparator", "quantity-range"]} - }, - "required": ["type"], - "allOf": [ - { - "if": { - "properties": {"type": {"const": "concept"}} - }, - "then": { - "properties": { - "type": {"const": "concept"}, - "selectedConcepts": { - "type": "array", - "minItems": 1, - "items": {"$ref": "#/definitions/termCode"}, - } - }, - "required": ["type", "selectedConcepts"] - } - }, - { - "if": { - "properties": {"type": {"const": "quantity-comperator"}} - }, - "then": { - "properties": { - "type": {"const": "quantity-comperator"}, - "comparator": { "enum": ["gt", "ge", "lt", "le", "eq", "ne"] }, - "value": { "type": "number" }, - "unit" : {"$ref": "#/definitions/unit" } - }, - "required": ["type", "comparator", "value"], - } - }, - { - "if" : { - "properties": {"type": {"const": "quantity-range"}} - }, - "then" : { - "properties": { - "type": {"const": "quantity-range"}, - "minValue": { "type": "number" }, - "maxValue": { "type": "number" }, - "unit" : {"$ref": "#/definitions/unit" } - }, - "required": ["type", "minValue", "maxValue"], - } - } - ] - } - }, - - "$id": "http://to_be_decided.com/query.schema.json", - "title": "queryDefinition", - "description": "Within a query the inclusion and exclusion criteria are conjuncted with AND NOT", - "type": "object", - "properties": { - "version": {"type": "string", "format": "uri"}, - "inclusionCriteria": { - "type": "array", - "minItems": 1, - "description": "All elements within the array are conjuncted with an AND operator", - "items": { - "type": "array", - "minItems": 1, - "description": "All elements within the array are conjuncted with an OR operator", - "items": { "$ref": "#/definitions/criterion" }, - }, - }, - "exclusionCriteria": { - "type": "array", - "minItems": 1, - "description": "All elements within the array are conjuncted with an OR operator", - "items": { - "type": "array", - "minItems": 1, - "description": "All elements within the array are conjuncted with an AND operator", - "items": { "$ref": "#/definitions/criterion" }, - }, - }, - "display" : {"type": "string"} - }, - "required": ["version", "inclusionCriteria" ] -} diff --git a/structured-query/json-schema/2021_10_18_StructuredQueryV2Schema.json b/structured-query/json-schema/2021_10_18_StructuredQueryV2Schema.json new file mode 100644 index 0000000..c2f23dc --- /dev/null +++ b/structured-query/json-schema/2021_10_18_StructuredQueryV2Schema.json @@ -0,0 +1,201 @@ +{ + "$schema": "http://to_be_decided.com/draft-2/schema#", + + "definitions": { + + "termCode": { + "type": "object", + "description": "The termCode defines a concept based on a coding system (i.e. LOINC). The triplet of code, system and version identify the concept.", + "properties": { + "code": { "type": "string" }, + "system": { "type": "string"}, + "version": { "type": "string"}, + "display": { "type": "string"} + }, + "required": ["code", "system", "display"], + }, + + "criterion": { + "type": "object", + "properties": { + "termCodes": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/definitions/termCode" } + }, + "valueFilter": { "$ref": "#/definitions/valueFilter"}, + "attributeFilters": { "$ref": "#/definitions/attributeFilters"}, + "timeRestriction": { "$ref": "#/definitions/timeRestriction"} + }, + "required": ["termCodes"] + }, + + "timeRestriction": { + "type": "object", + "description": "TimeRestirction specify the interval within the critiera has to be fullfilled. An intersection of the criterias interval with the interval defined in this timeRestriction is sufficient", + "properties": { + "beforeDate": { "type": "string", "format": "date"}, + "afterDate": { "type": "string", "format": "date"} + }, + "anyOf": [ {"required": ["beforeDate"]}, {"required": ["afterDate"]}] + }, + + "unit": { + "type": "object", + "title": "UCUM Unit", + "description": "The unit is a ucum unit (https://ucum.org/trac)", + "properties": { + "code": { "type": "string" }, + "display": {"type": "string"} + }, + "required": ["code", "display"] + }, + + "attributeFilters": { + "type": "array", + "items": {"$ref": "#/definitions/attributeFilter"} + }, + + "valueFilter": { + "type": "object", + "properties": { + "type": { "enum": ["concept", "quantity-comparator", "quantity-range"]} + }, + "required": ["type"], + "allOf": [ + { + "if": { + "properties": {"type": {"const": "concept"}} + }, + "then": { + "properties": { + "type": {"const": "concept"}, + "selectedConcepts": { + "type": "array", + "minItems": 1, + "items": {"$ref": "#/definitions/termCode"} + } + }, + "required": ["type", "selectedConcepts"] + } + }, + { + "if": { + "properties": {"type": {"const": "quantity-comperator"}} + }, + "then": { + "properties": { + "type": {"const": "quantity-comperator"}, + "comparator": { "enum": ["gt", "ge", "lt", "le", "eq", "ne"] }, + "value": { "type": "number" }, + "unit" : {"$ref": "#/definitions/unit" } + }, + "required": ["type", "comparator", "value"] + } + }, + { + "if" : { + "properties": {"type": {"const": "quantity-range"}} + }, + "then" : { + "properties": { + "type": {"const": "quantity-range"}, + "minValue": { "type": "number" }, + "maxValue": { "type": "number" }, + "unit" : {"$ref": "#/definitions/unit" } + }, + "required": ["type", "minValue", "maxValue"] + } + } + ] + }, + + "attributeFilter": { + "type": "object", + "properties": { + "type": { "enum": ["concept", "quantity-comparator", "quantity-range"]} + }, + "required": ["type"], + "allOf": [ + { + "if": { + "properties": {"type": {"const": "concept"}} + }, + "then": { + "properties": { + "attributeCode": {"$ref": "#/definitions/termCode"}, + "type": {"const": "concept"}, + "selectedConcepts": { + "type": "array", + "minItems": 1, + "items": {"$ref": "#/definitions/termCode"} + } + }, + "required": ["type", "selectedConcepts", "attributeCode"] + } + }, + { + "if": { + "properties": {"type": {"const": "quantity-comperator"}} + }, + "then": { + "properties": { + "attributeCode": {"$ref": "#/definitions/termCode"}, + "type": {"const": "quantity-comperator"}, + "comparator": { "enum": ["gt", "ge", "lt", "le", "eq", "ne"] }, + "value": { "type": "number" }, + "unit" : {"$ref": "#/definitions/unit" } + }, + "required": ["type", "comparator", "value", "attributeCode"] + } + }, + { + "if" : { + "properties": {"type": {"const": "quantity-range"}} + }, + "then" : { + "properties": { + "attributeCode": {"$ref": "#/definitions/termCode"}, + "type": {"const": "quantity-range"}, + "minValue": { "type": "number" }, + "maxValue": { "type": "number" }, + "unit" : {"$ref": "#/definitions/unit" } + }, + "required": ["type", "minValue", "maxValue", "attributeCode"] + } + } + ] + } + }, + "$id": "http://to_be_decided.com/query.schema.json", + "title": "queryDefinition", + "description": "Within a query the inclusion and exclusion criteria are conjuncted with AND NOT", + "type": "object", + "properties": { + "version": {"type": "string", "format": "uri"}, + "inclusionCriteria": { + "type": "array", + "minItems": 1, + "description": "All elements within the array are conjuncted with an AND operator", + "items": { + "type": "array", + "minItems": 1, + "description": "All elements within the array are conjuncted with an OR operator", + "items": { "$ref": "#/definitions/criterion" } + } + }, + "exclusionCriteria": { + "type": "array", + "minItems": 1, + "description": "All elements within the array are conjuncted with an OR operator", + "items": { + "type": "array", + "minItems": 1, + "description": "All elements within the array are conjuncted with an AND operator", + "items": { "$ref": "#/definitions/criterion" } + } + }, + "display" : {"type": "string"} + }, + "required": ["version", "inclusionCriteria" ] +}