3

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に対応する一致の値を取得します。これにより、ツリーの下で同じことが行われる可能性があります。

4

2 に答える 2

1

あなたのユースケースは、「原型化された」openEHR データを照会しているようです。

ユースケースと同様のリクエストに xQuery を使用しているオープン ソースhttps://github.com/LiU-IMT/EEEを自由に見てください。ただし、データのモデル化は少し異なります。

これは、例えば論文http://www.ep.liu.se/ecp/070/009/ecp1270009.pdfで使用され、組織学的検査結果が腫瘍性病変を示すすべてのレコード ID を返すクエリの例を見つけることができます。 2006 年 1 月 1 日および 2006 年 5 月 1 日。

AQL (Archetype Query Language) では、次のように表現されます...

SELECT e/ehr_id/value as ehr_id
FROM Ehr e
CONTAINS VERSION v
CONTAINS COMPOSITION c [openEHR-EHR-COMPOSITION.histologic_exam.v1]
CONTAINS OBSERVATION obs [openEHR-EHR-   OBSERVATION.histological_exam_result.v1]
WHERE (EXISTS obs/data[at0001]/events[at0002]/data[at0003]/items[at0085]/items[at0033]/items[at0034] 
OR
EXISTS obs/data[at0001]/events[at0002]/data[at0003]/items[at0085]/items[at0033]/items[at0035])
AND c/context/start_time/value >= '2006-01-01T00:00:00,000+01:00'
AND c/context/start_time/value < '2006-05-01T00:00:00,000+01:00'`

...自動的に解析されて XQuery に変換されると、次のようになります。

declare namespace v1 = "http://schemas.openehr.org/v1";
declare default element namespace "http://schemas.openehr.org/v1";
declare namespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
declare namespace eee = "http://www.imt.liu.se/mi/ehr/2010/EEE-v1.xsd";
declare namespace res = "http://www.imt.liu.se/mi/ehr/2010/xml-result-v1#";
<res:xml-results>
<res:head><res:variable name="ehr_id"/></res:head>
<res:results>
 {let $ehrRoot := //eee:EHR
  for $e in $ehrRoot
  for $v in $e/eee:versioned_objects/eee:versions
  for $c in $v//*[@xsi:type='v1:COMPOSITION' and @archetype_node_id="openEHR-EHR-COMPOSITION.histologic_exam.v1"]
  for $obs in $c//*[@xsi:type='v1:OBSERVATION' and @archetype_node_id= "openEHR-EHR-OBSERVATION.histological_exam_result.v1"]
  where
   (
    exists($obs/data[@archetype_node_id = 'at0001']/events[@archetype_node_id = 'at0002']/data[@archetype_node_id='at0003']/items[@archetype_node_id = 'at0085']/items[@archetype_node_id = 'at0033']/items[@archetype_node_id = 'at0034'])
   or
    exists($obs/data[@archetype_node_id = 'at0001']/events[@archetype_node_ id = 'at0002']/data[@archetype_node_id = 'at0003']/items[@archetype_node_id = 'at0085']/items[@archetype_node_id = 'at0033']/items[@archetype_node_id = 'at0035'])
   )
   and
    $c/context/start_time/value >= '2006-01-01T00:00:00,000+01:00' 
   and 
    $c/context/start_time/value < '2006-05-01T00:00:00,000+01:00'
return
<res:result><res:binding name="ehr_id">{$e/eee:ehr_id/value}</res:binding></res:result>}
</res:results>
</res:xml-results>

このパターンは、ユースケースでも試す価値があるかもしれません。ソリューションとコンテキストの詳細については、論文http://www.biomedcentral.com/1472-6947/13/57を参照してください。

于 2015-08-14T22:03:56.930 に答える
0

ツリーが二分探索ツリーの場合、これは XQuery を使用して実装されています。この投稿を参照してください。

http://dnovatchev.wordpress.com/2012/01/09/the-binary-search-tree-data-structurehaving-fun-with-xpath-3-0/

これは使用するには遅すぎるかもしれません...しかし...抽象ツリーに関してすでに定義されている具体的なツリーの上に抽象ツリーを実装しているようです。XML要素でツリーを実装する代わりに、要素ツリーを直接使用してください...

于 2014-06-24T16:22:31.323 に答える