はじめに
第3回目はAQL(Archetype Query Language)を使ってEHRbaseに対してクエリーを発行します。
* AQLとはなにか
* 文法概要
* サンプル
* EHRbaseのAQL API
* 書き方
* 参考資料
AQLとはなにか
Archetype Query Languageの略で、SQLに似た文法でEHRに対して統一的に問い合わせ(query)を発行することができます.
統一されたQueryインターフェースがあるので、システムに依存することなくアプリケーションを開発することができます。
現在の実装はANTLRをベースに行われていて、言語による差がなく広まっています。AQLを使いこなすことがopenEHR活用の鍵です。
文法概要
AQLはSQLに似ています。SELECT, FROM, WHERE, ASはほぼ同じ意味を持ちます。重要なのはパスです。Archetypeのパスの考え方についてはこちらをご覧ください。
- SELECT: 取得する項目を指定します。
- FROM: 取得する対象を指定します
- WHERE: 取得する条件を指定します
- AS: 別名を指定します。
サンプル
SELECT c/context/start_time/value, obs/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude
FROM COMPOSITION c CONTAINS OBSERVATION obs [openEHR-EHR-OBSERVATION.temperature.v1]
WHERE obs/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude >= 38.0
EHRbaseのAQL API
- GET, POSTともに準備されています。
- GET
GET /rest/openehr/v1/query/aql
パラメータ
key | value |
---|---|
q | AQL文 |
fetch | 取得するデータの数を指定 |
- POST
POST /rest/openehr/v1/query/aql
Bodyにqをキーとして値にAQLを書いたJSONを
key | value |
---|---|
q | AQL文 |
- 結果
key | value |
---|---|
q | AQL文 |
columns | データのパスとデータ列の順番 |
rows | データ本体 |
書き方
AQLはFROM, WHERE, SELECTの順に書いていくとわかりやすいです。
- FROMでデータ取得の対象を指定します。
- WHEREで条件を指定します。
- 最後にSELECTで取得する項目を指定します。
「38度以上の発熱がある患者のEHR IDと、発熱時の症状も取得する」ことを例にとって解説します。
サンプルデータは以下のソースコードで rais db:seed を行ってランダムに作成したものを使います。
FROM
「38度以上の発熱がある患者のEHR IDと、発熱時の症状も取得する」には以下のようなデータセットが含まれると考えます。
- EHRの中で体温が記録されているアーキタイプ(openEHR-EHR-OBSERVATION.temperature.v1)を含むCOMPOSITION。
- 上記のCOMPOSITIONを含むEHR
AQLで記述するとこうなります。
FROM EHR e CONTAINS COMPOSITION c
CONTAINS OBSERVATION obs [openEHR-EHR-OBSERVATION.temperature.v1]
WHERE
「38度以上の発熱がある患者のEHR IDと、発熱時の症状も取得する」は以下のような条件であると考えます。
- 体温を示すarchetype(openEHR-EHR-OBSERVATION.temperature.v1)の値を示すパス(/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude)が38.0以上であること
AQLで記述するとこうなります。
WHERE obs/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude >= 38.0"
SELECT
「38度以上の発熱がある患者のEHR IDと、発熱時の症状も取得する」で取得すべきは以下の項目です。
- 体温を示すアーキタイプのパス
- EHRのehr_id
- 症状を示すアーキタイプのパス
SELECT文で指定すると以下のようになります。
SELECT e/ehr_id/value,
obs/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude,
c/content[openEHR-EHR-OBSERVATION.story.v1]/data[at0001]/events[at0002]/data[at0003]/items[openEHR-EHR-CLUSTER.symptom_sign.v1]/items[at0001]/value
まとめ
以上をSELECT, FROM, WHEREの順につなげます。
SELECT e/ehr_id/value, obs/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude, c/content[openEHR-EHR-OBSERVATION.story.v1]/data[at0001]/events[at0002]/data[at0003]/items[openEHR-EHR-CLUSTER.symptom_sign.v1]/items[at0001]/value FROM EHR e CONTAINS COMPOSITION c CONTAINS OBSERVATION obs [openEHR-EHR-OBSERVATION.temperature.v1] WHERE obs/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude >= 38.0
Postmanから実行すると以下のような結果が返ってきます。
{
"q": "SELECT e/ehr_id/value, obs/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude, c/content[openEHR-EHR-OBSERVATION.story.v1]/data[at0001]/events[at0002]/data[at0003]/items[openEHR-EHR-CLUSTER.symptom_sign.v1]/items[at0001]/value FROM EHR e CONTAINS COMPOSITION c CONTAINS OBSERVATION obs [openEHR-EHR-OBSERVATION.temperature.v1] WHERE obs/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude >= 38.0",
"columns": [
{
"path": "/ehr_id/value",
"name": "#0"
},
{
"path": "/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/magnitude",
"name": "#1"
},
{
"path": "/content[openEHR-EHR-OBSERVATION.story.v1]/data[at0001]/events[at0002]/data[at0003]/items[openEHR-EHR-CLUSTER.symptom_sign.v1]/items[at0001]/value",
"name": "#2"
}
],
"rows": [
[
"04e27e6b-e9bf-4573-ae30-a3cd46a766c6",
"38.0",
{
"value": "咳"
}
],
[
"04e27e6b-e9bf-4573-ae30-a3cd46a766c6",
"38.0",
{
"value": "発熱"
}
],
[
"04e27e6b-e9bf-4573-ae30-a3cd46a766c6",
"38.1",
{
"value": "倦怠感"
}
],
参考資料
- openEHR Archetype Query Language, https://specifications.openehr.org/releases/QUERY/latest/AQL.html
- パスとロケーター: https://trac.openehr.jp/wiki/Archtectural%20Overview%20Paths
- openEHR REST Query API: https://specifications.openehr.org/releases/ITS-REST/Release-1.0.0/query.html#query-execute-query-post