Skip to main content

LifeOmic FHIR Service DSL

LifeOmic FHIR Service DSL(Domain Specific Language) enables you to perform advanced searching and advanced analytics on FHIR resources using the Elasticsearch Query DSL and Elasticsearch Aggregations APIs.

Data Types

The following table shows data type mappings between FHIR and Elasticsearch. All other data types in FHIR compose or extend the data types listed in the table below. Data types that extend the data types listed below are assumed to map to the same Elasticsearch data type unless otherwise noted.

FHIRElasticsearch
base64Binarytext / keyword
booleanboolean
datedate
dateTimedate
decimalnumeric
instantdate
integernumeric
stringtext / keyword
timedate
uritext / keyword

Understanding Text and Keyword Data Types

Elasticsearch has two different "string" data types: text and keyword.

Each of these data types are useful in different scenarios. text fields are analyzed and are used to perform full text queries. keyword fields are used for filtering, sorting and aggregations.

In the LifeOmic FHIR Service DSL, all "string" like fields are represented as both text and keyword fields as a multi-field. The root field for every datatype is a text field and the sub-field "keyword" is a keyword field.

For example, consider the FHIR Patient identifier.value field:

In the FHIR schema, this field is a string data type. In LifeOmic FHIR Service DSL this field exists as identifier.value as a text datatype and as identifier.value.keyword as a keyword datatype.

The DSL Language

LifeOmic FHIR Service DSL is a SQL AST (Abstract Syntax Tree) and super-set of the Elasticsearch Query DSL and Elasticsearch Aggregations APIs.

Select Statement

Retrieves all FHIR resources from the targeted table.

JMES PathDefinitionOptional
type"select"
columns"*" or an Object Identifier
fromA Table Identifier
whereA Where ClauseYes
orderbyAn Order-By ClauseYes
limitA Limit ClauseYes

Examples

Get all Patient resources

{
"type": "select",
"columns": "*",
"from": [
{
"table": "patient"
}
]
}

Get all Patient resource id values

{
"type": "select",
"columns": [
{
"expr": {
"type": "column_ref",
"column": "id.keyword"
}
}
],
"from": [
{
"table": "patient"
}
]
}

Object Identifier

JMES PathDefinition
[*]One or more Column Identifiers

or

JMES PathDefinition
[0].type"elasticsearch"
[0].aggregationsAn Elasticsearch Aggregation

Examples

Identify multiple columns

[
{
"expr": {
"type": "column_ref",
"column": "id.keyword"
}
},
{
"expr": {
"type": "column_ref",
"column": "effectiveDateTime"
}
}
]

Count the number of id values

[
{
"type": "elasticsearch",
"aggregations": {
"results": {
"value_count": {
"field": "id.keyword"
}
}
}
}
]

Estimate the number of subject.reference values

[
{
"type": "elasticsearch",
"aggregations": {
"results": {
"cardinality": {
"field": "subject.reference.keyword"
}
}
}
}
]

Column Identifier

JMES PathDefinition
expr.type"column_ref"
expr.columnA FHIR resource field name

Table Identifier

A table identifer is a FHIR resources type written in snake_case. For example, DiagnosticReport becomes disagnostic_report.

JMES PathDefinition
[0].tableA FHIR resource name

Where Clause

JMES PathDefinition
type"elasticsearch"
queryAn Elasticsearch Query DSL
highlightAn Elasticsearch Highlighter

Examples

Filter where the gender is "male"

{
"type": "elasticsearch",
"query": {
"term": {
"gender.keyword": "male"
}
}
}

Filter where the valueInteger is greater than 10

{
"type": "elasticsearch",
"query": {
"range": {
"valueInteger": {
"gt": 10
}
}
}
}

Highlight the Diagnostic Report subject.reference

{
"type": "select",
"columns": "*",
"from": [
{
"table": "diagnostic_report"
}
],
"where": {
"type": "elasticsearch",
"query": {
"bool": {
"must": {
"match": {
"text.div": "important"
}
}
}
},
"highlight": {
"fields": {
"text.div": {}
}
}
}
}

Order-By Clause

JMES PathDefinition
[*].typeASC or DESC
[*].exprA Column Identifier

Examples

Order results by the id.keyword field

{
[
{
"type": "ASC",
"expr": {
"type": "column_ref",
"column": "id.keyword"
}
}
]
}

Limit Clause

JMES PathDefinition
[0].type"number"
[0].valueThe offset as a nonnegative numeric integer
[1].type"number"
[1].valueThe limit as a nonnegative numeric integer

or

JMES PathDefinition
[0].type"elasticsearch"
[0].search_afterAn Elasticsearch Search After clause
[1].type"number"
[1].valueThe limit as a nonnegative numeric integer

Note: A Search-After clause must be used in conjunction with an Order By Clause

Examples

Limit the result to 100 results

[
{
"type": "number",
"value" 0
},
{
"type": "number",
"value" 100
}
]

Get results 11 through 20

[
{
"type": "number",
"value" 10
},
{
"type": "number",
"value" 10
}
]

Get the next 10 results after "50619f8c-10aa-464a-a227-90a7aa6ffd43"

[
{
"type": "elasticsearch",
"search_after": [
"50619f8c-10aa-464a-a227-90a7aa6ffd43"
]
},
{
"type": "number",
"value" 10
}
]

Scrolling

When using scrolling, the limit clause is only recognized for the initial request. For each subsequent request, the limit is duplicated and the offset is automatically adjusted. Altering the limit clause will have no effect.

For example, if the offset and limit are set to 0 and 100, the first request will return the first 100 results (1 - 100), and the next request will return the next 100 results (101 - 200).

Scrolling is not compatible with the Elasticsearch Search-After clause.

Response

The response is a standard Elasticsearch Search Response Body. The following is a breakdown of the individual fields in the object described using JMES Path notation.

JMES PathDefinition
tookThe amount of time it took the server to respond.
timed_outtrue if the server timed out, false otherwise.
shardsAn overview of the shards scanned.
shards.totalThe number of shards scanned. Additional shards can be requested by contacting LifeOmic.
shards.successfulThe number of shards scanned successfully.
shards.skippedThe number of shards skipped.
shards.failedThe number of shards scanned that failed.
hitsAn overview of the FHIR resources found.
hits.totalThe total number of FHIR resources found during scanning.
hits.total.valueThe total number of FHIR resources found during scanning.
hits.total.relationeq if hits.total is less than 10,000, gte otherwise.
hits.max_scoreThe maximum relative relevancy.
hits.hitsThe resources returned.
hits.hits[*]._indexThe index the FHIR resources belong to.
hits.hits[*]._typeAlways _doc.
hits.hits[*]._idA Base64 encoded Resource LRN.
hits.hits[*]._scoreThe FHIR resource relevancy.
hits.hits[*]._sourceThe FHIR resource, whose schema matches the official FHIR schema defined by the FHIR specification. A full list of FHIR resources can be found at the FHIR Resource List.
aggregationsThe aggregation results. See the Elasticsearch Aggregations documentation for additional information.