SQLとエンティティ値属性ベースのデータベース設計を使用してツリー構造クエリメカニズムを実装しました。タスクにXQueryを使用できると仮定して、XQueryベースのアプローチで同じ機能のパフォーマンスを確認したかったのです。私のツリー(XLMドキュメント)の簡略化された形式は次のとおりです。
ノードにはさまざまなタイプがありますが、クエリで使用している属性は、ノードのarchetype_node_id属性のみです。私が書き込もうとしたテストクエリは、2つの要素ノードを持つ評価ノード(右側)を選択することを目的としています。クエリの実装には、使用する言語の2つの主要な機能が必要です。構造定義をサポートする機能(ブール演算子を使用)と、ノードの属性(この場合はxml属性)の制約を定義する機能です。
XQueryでは、2つの問題があります1)関心のあるすべてのノード、つまりグラフに関心のあるノードへの参照を宣言できないようです2)一致を返す方法がわかりません、このツリーの右側の一致は1つの構成になり、評価には2つの要素が含まれるためです。
これが、FLWRを使用した最初の素朴な試みです。
for $composition in doc("composition-visit.xml")//element()
let $evaluation := (
for $evalsneeded in $composition//element()
let $elementat02 :=
(for $el02 in $evalsneeded//element()
where $el02/@archetype_node_id = 'at0002'
and exists($evalsneeded//$el02)
return $el02
),
$elementat03 :=
(for $el03 in $evalsneeded//element()
where $el03/@archetype_node_id = 'at0003'
and exists($evalsneeded//$el03)
return $el03
)
where $evalsneeded/@archetype_node_id = 'openEHR-EHR-EVALUATION.goal.v1'
and
exists ($evalsneeded//$elementat02)
and
exists ($evalsneeded//$elementat03)
return $evalsneeded)
where $composition/@archetype_node_id = 'openEHR-EHR-COMPOSITION.encounter.v1'
and exists($composition//$evaluation)
return $evaluation/@archetype_node_id/string(.)
私の問題は、評価ノードと要素ノードをサブクエリにプッシュすることです。これらをメインのFLOWR本体にグローバル変数として導入すると、属性値と場所に基づくフィルタリングが機能しないためです。
結果を返すことに関しては、私はさらに無知ですが、それについて別の質問をしたくありませんでした。
理想的には、at0002コードとat0003コードの両方を持つ要素を持つ評価にAND制約を適用する場合、ツリーの右側を取得する必要があります。同じ要素にOR制約を使用する場合は、ツリー全体を取得する必要があります。
これはXQueryで実行できますか?これは、ツリーで探している構造の存在のテストとして機能しますが、個々のノードにもアクセスしたいと思います。
更新:これが私の2回目の試みです。これは実際に私がやろうとしていたことへの扉を開きますが、これがXQueryでこれを行う正しい方法であるかどうかはわかりません。このアプローチを改善するために別の質問をする必要がありますか?:
<result>
{
for $composition in doc("composition-visit.xml")//element()
where $composition/@archetype_node_id = 'openEHR-EHR-COMPOSITION.encounter.v1'
return <composition>
<name>{$composition/name/value/string(.)}</name>
<evaluation>{for $eval in $composition//element()
let $el1 := (for $el1_in_eval in $eval//element()
where $el1_in_eval/@archetype_node_id = 'at0002'
return $el1_in_eval ),
$el2 := (for $el2_in_eval in $eval//element()
where $el2_in_eval/@archetype_node_id = 'at0003'
return $el2_in_eval )
where $eval/@archetype_node_id = 'openEHR-EHR-EVALUATION.goal.v1'
and
(exists($el1)
and
exists($el2)
)
return <eval>
<name>{$eval/name/value/string(.)}</name>
<element1>{for $element1 in $eval//element()
where $element1/@archetype_node_id = 'at0002'
return $element1}</element1>
<element2>{for $element2 in $eval//element()
where $element2/@archetype_node_id = 'at0003'
return $element2}</element2>
</eval>
}</evaluation>
</composition>
}
</result>
基本的に、私はletステートメントで親子関係を強制し、returnを使用して、letに対応する一致の値を取得します。これにより、ツリーの下で同じことが行われる可能性があります。