Skip to content

Commit

Permalink
Add explicit license text on index page
Browse files Browse the repository at this point in the history
  • Loading branch information
johngrimes committed Sep 20, 2024
1 parent 91f3bdd commit f5b3df1
Showing 1 changed file with 127 additions and 86 deletions.
213 changes: 127 additions & 86 deletions input/pagecontent/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,113 +37,146 @@ that comprise essential data elements. The availability of these view
definitions will greatly reduce the need for analysts to perform repetitive and
redundant transformation tasks for common use cases.

Let's start with a simple example, defining a "patient_demographics" and "diagnoses" views with
Let's start with a simple example, defining a "patient_demographics" and "
diagnoses" views with
the following [ViewDefinition](StructureDefinition-ViewDefinition.html)
structure:

```json
{
"resourceType": "ViewDefinition",
"resource": "patient",
"name": "patient_demographics",
"select": [
{
"column": [
{"name": "patient_id", "path": "getResourceKey()"},
{"name": "gender", "path": "gender"},
{"name": "dob", "path": "birthDate"}
],
{
"forEach": "name.where(use = 'official').first()",
"column": [
{"path": "given.join(' ')", "name": "given_name",},
{"path": "family", "name": "family_name"}
]
}

}
]}
"resourceType": "ViewDefinition",
"resource": "patient",
"name": "patient_demographics",
"select": [
{
"column": [
{
"name": "patient_id",
"path": "getResourceKey()"
},
{
"name": "gender",
"path": "gender"
},
{
"name": "dob",
"path": "birthDate"
}
],
{
"forEach": "name.where(use = 'official').first()",
"column": [
{
"path": "given.join(' ')",
"name": "given_name"
},
{
"path": "family",
"name": "family_name"
}
]
}

}
]
}
```


| id | gender | dob | given_name | family_name |
|---------------|--------|------------|---------------|-------------|
| ------------- | ------ | ---------- | ------------- | ----------- |
| 5e23837b-.... | female | 1952-03-08 | Malvina Gerda | Vicario |
| 93f09189-.... | male | 1981-08-08 | Yolotzin Adel | Bristow |
| 44d86263-.... | other | 2015-01-28 | Jin Gomer | Aarens |
{:.table-data}



```json
{
"resourceType": "ViewDefinition",
"resource": "condition",
"name": "diagnoses_view",
"select": [
{
"column": [
{"name": "condition_id", "path": "id"},
{"name": "onset", "path": "onset.dateTime"},
{"name": "abatement", "path": "abatement.dateTime"},
{"name": "status", "path": "clinicalStatus.coding.code.first()"},
{"name": "code", "path": "code.coding.where(system='http://snomed.info/sct').code.first()"},
{"name": "display", "path": "code.text"},
{"name": "patient_id", "path": "subject.id"}
]
}
]
"resourceType": "ViewDefinition",
"resource": "condition",
"name": "diagnoses_view",
"select": [
{
"column": [
{
"name": "condition_id",
"path": "id"
},
{
"name": "onset",
"path": "onset.dateTime"
},
{
"name": "abatement",
"path": "abatement.dateTime"
},
{
"name": "status",
"path": "clinicalStatus.coding.code.first()"
},
{
"name": "code",
"path": "code.coding.where(system='http://snomed.info/sct').code.first()"
},
{
"name": "display",
"path": "code.text"
},
{
"name": "patient_id",
"path": "subject.id"
}
]
}
]
}

```

| condition_id | onset | status | code | display | patient_id |
|--------------|---------------------------|----------|-----------|-------------------------------------------|---------------|
| 011b6e34-... | 2016-08-06T02:13:33+03:00 | resolved | 444814009 | Viral sinusitis (disorder) | 5e23837b-.... |
| 014774ea-... | 2016-05-27T13:44:17+03:00 | resolved | 195662009 | Acute viral pharyngitis (disorder) | 93f09189-.... |
| 02116b05-... | 2003-02-14T18:25:00+03:00 | resolved | 195662009 | Acute viral pharyngitis (disorder) | 44d86263-.... |
| 0287a9bc-... | 2019-03-30T08:53:34+03:00 | resolved | 10509002 | Acute bronchitis (disorder) | 41907da4-.... |
| 02a79009-... | 2013-07-04T14:17:52+04:00 | resolved | 43878008 | Streptococcal sore throat (disorder) | 5bad6369-.... |
| 02bfc9af-... | 2016-10-06T05:24:13+03:00 | resolved | 195662009 | Acute viral pharyngitis (disorder) | 8742d4ba-.... |
| condition_id | onset | status | code | display | patient_id |
| ------------ | ------------------------- | -------- | --------- | ------------------------------------ | ------------- |
| 011b6e34-... | 2016-08-06T02:13:33+03:00 | resolved | 444814009 | Viral sinusitis (disorder) | 5e23837b-.... |
| 014774ea-... | 2016-05-27T13:44:17+03:00 | resolved | 195662009 | Acute viral pharyngitis (disorder) | 93f09189-.... |
| 02116b05-... | 2003-02-14T18:25:00+03:00 | resolved | 195662009 | Acute viral pharyngitis (disorder) | 44d86263-.... |
| 0287a9bc-... | 2019-03-30T08:53:34+03:00 | resolved | 10509002 | Acute bronchitis (disorder) | 41907da4-.... |
| 02a79009-... | 2013-07-04T14:17:52+04:00 | resolved | 43878008 | Streptococcal sore throat (disorder) | 5bad6369-.... |
| 02bfc9af-... | 2016-10-06T05:24:13+03:00 | resolved | 195662009 | Acute viral pharyngitis (disorder) | 8742d4ba-.... |
{:.table-data}


Such tabular views can be created for any FHIR resource,
with [more examples here](artifacts.html#example-example-instances). See
the [View Definition page](StructureDefinition-ViewDefinition.html) for the full
definition of the above structure.

The views can be persisted and queried in your database of choice, using the view
The views can be persisted and queried in your database of choice, using the
view
name as the table name:

```sql
SELECT DATE_PART('year', AGE(pt.dob::timestamp)) AS age,
gender,
dg.code,
dg.display,
count(*)
FROM patient_demographics pt
JOIN diagnoses dg using (patient_id)
GROUP BY 1,2,3,4
ORDER BY 1, 5 desc
SELECT DATE_PART('year', AGE(pt.dob::timestamp)) AS age,
gender,
dg.code,
dg.display,
count(*)
FROM patient_demographics pt
JOIN diagnoses dg using (patient_id)
GROUP BY 1, 2, 3, 4
ORDER BY 1, 5 desc
```

Example output:

|age| gender|code|display countr|
----|-------|----|--------------|
|7| female| 444814009| Viral sinusitis (disorder)| 1340
|7| female| 65363002| Otitis media| 2345
|7| female| 43878008| Streptococcal sore throat (disorder)| 42
| age | gender | code | display countr |
| --- | ------ | --------- | ------------------------------------ | ---- |
| 7 | female | 444814009 | Viral sinusitis (disorder) | 1340 |
| 7 | female | 65363002 | Otitis media | 2345 |
| 7 | female | 43878008 | Streptococcal sore throat (disorder) | 42 |
{:.table-data}


### Non-goals

View Definitions are intentionally constrained to a narrow set of functionality
to make them easily and broadly implementable, while deferring higher-level
capabilities to database engines or processing pipelines that solve those
problems well. Therefore it's important to know what View Definitions do *not*
problems well. Therefore it's important to know what View Definitions do _not_
do, by design:

#### A single View Definition will not join different resources in any way
Expand All @@ -159,15 +192,15 @@ pipelines join as needed.

View Definitions define only the logical schema of views, and therefore defer
sorting, aggregation or limit operations to engines, along with cross-view
joins. *View Runners* (described below) or future FHIR server operations may
joins. _View Runners_ (described below) or future FHIR server operations may
accept limits or sort columns as part of their operations, so users at runtime
can specify what they need dynamically and independently of the definition of
the view itself.

#### View Definitions are not aware of output formats

View Definitions themselves are independent of any tech stack and therefore
unaware of the output format. *View Runners* are the component that applies
unaware of the output format. _View Runners_ are the component that applies
definitions to a particular stack, producing output like a database table,
Parquet file, CSV, or another format specific to the runner.

Expand All @@ -177,9 +210,9 @@ The [View Definition](StructureDefinition-ViewDefinition.html) is the central
element of this spec, but in practice it is only one layer within a larger
system. A broader view of the system includes three layers:

- The *Data Layer*;
- The *View Layer*, and;
- The *Analytics Layer*.
- The _Data Layer_;
- The _View Layer_, and;
- The _Analytics Layer_.

<img src="layers.svg" alt="High-level diagram of layers" style="float: none; width: 700px"/>

Expand All @@ -188,7 +221,7 @@ system. A broader view of the system includes three layers:
#### Data Layer

The Data Layer is a set of lossless representations that collectively enable
FHIR to be used with a wide variety of different query technologies.
FHIR to be used with a wide variety of different query technologies.

The Data Layer may optionally be persisted and annotated to make implementations
of the View Layer more efficient, but no specific Data Layer structure will be
Expand All @@ -204,11 +237,11 @@ patterns.

The View Layer has two key components:

* *View Definitions*, allowing users to define flattened views of FHIR data that
are portable between systems.
* *View Runners*, system-specific tools or libraries that apply view definitions
to the underlying data layer, optionally making use of annotations to optimize
performance.
- _View Definitions_, allowing users to define flattened views of FHIR data that
are portable between systems.
- _View Runners_, system-specific tools or libraries that apply view definitions
to the underlying data layer, optionally making use of annotations to optimize
performance.

See [View Definition](StructureDefinition-ViewDefinition.html) for more details
and examples.
Expand All @@ -218,14 +251,18 @@ have one or more corresponding view runners, but a given View Definition can be
run by many runners over many data layers.

There are two popular categories of runners:
* **In-memory runner** consume resources, flatten, and output results into a stream, a file or a table.
You can imagine the ETL pipeline from FHIR Bulk export ndjson files transformed into parquet files.
* **In-database runner** translate ViewDefinition into SQL query over an FHIR-native database.
In that case the view can be a real database view or table. In-database runner could be way more efficient than in-memory
,speed and storage resources but much more complex for implementers.

<img src="viewdef-runners.jpeg" alt="Diagram comparing in-memory and in-database runners" style="float: none; width: 100%">
- **In-memory runner** consume resources, flatten, and output results into a
stream, a file or a table.
You can imagine the ETL pipeline from FHIR Bulk export ndjson files
transformed into parquet files.
- **In-database runner** translate ViewDefinition into SQL query over an
FHIR-native database.
In that case the view can be a real database view or table. In-database runner
could be way more efficient than in-memory
,speed and storage resources but much more complex for implementers.

<img src="viewdef-runners.jpeg" alt="Diagram comparing in-memory and in-database runners" style="float: none; width: 100%">

#### The Analytics Layer

Expand All @@ -237,10 +274,14 @@ intelligence tools.

### Glossary

See the [Glossary](glossary.html) for the definitions of terms used in this specification.
See the [Glossary](glossary.html) for the definitions of terms used in this
specification.

### License

This specification is dedicated to the public domain under
[CC0](https://creativecommons.org/publicdomain/zero/1.0/).

FHIR® is the registered trademark of HL7 and is used with the permission of HL7.
Use of the FHIR trademark does not constitute endorsement of the contents of
this repository by HL7, nor affirmation that this data is conformant to the
Expand Down

0 comments on commit f5b3df1

Please sign in to comment.