Tree XQuery能否支持树结构查询?
我使用sql和基于实体-值-属性的数据库设计实现了树结构查询机制。 我希望通过基于XQuery的方法查看相同功能的性能,假设可以使用XQuery完成任务。 我的树(XLM文档)的简化形式如下: 有不同类型的节点,但我在查询中使用的唯一属性是节点的archetype\u node\u id属性。我尝试编写的测试查询旨在选择包含2个元素节点的求值节点(右侧)。查询实现需要所用语言的两个关键功能:支持结构定义(使用布尔运算符)的能力,以及定义节点属性约束(本例中为xml属性)的能力 对于XQuery,我有两个问题 1) 我似乎无法声明对所有感兴趣的节点的引用,即我在图中感兴趣的任何节点 2) 我不知道如何返回匹配项,因为这棵树右侧的匹配项将有一个组合和一个评估,而评估又有两个元素 以下是我第一次使用FLWR的天真尝试:Tree XQuery能否支持树结构查询?,tree,xquery,openehr,Tree,Xquery,Openehr,我使用sql和基于实体-值-属性的数据库设计实现了树结构查询机制。 我希望通过基于XQuery的方法查看相同功能的性能,假设可以使用XQuery完成任务。 我的树(XLM文档)的简化形式如下: 有不同类型的节点,但我在查询中使用的唯一属性是节点的archetype\u node\u id属性。我尝试编写的测试查询旨在选择包含2个元素节点的求值节点(右侧)。查询实现需要所用语言的两个关键功能:支持结构定义(使用布尔运算符)的能力,以及定义节点属性约束(本例中为xml属性)的能力 对于XQuery
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(.)
我的问题是,我最终将求值和元素节点推送到子查询,因为如果我将它们作为全局变量引入到主Flower主体中,那么基于它们的属性值和位置的过滤将不起作用
在返回结果的问题上,我甚至更加不知所措,但我不想就此提出单独的问题
理想情况下,当我对同时包含at0002和at0003代码的元素的求值执行AND约束时,我应该得到树的右侧,如果我对相同的元素使用OR约束,我应该得到整个树
这在XQuery中可行吗?它可以用来测试我在树中寻找的结构是否存在,但我也想访问各个节点
更新:这是我的第二次尝试。这一步实际上为我一直在尝试做的事情打开了大门,但我不确定在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>
{
对于文档中的$composition(“composition visit.xml”)//元素()
其中$composition/@archetype\u node\u id='openEHR-composition.conference.v1'
返回
{$composition/name/value/string(.)}
{对于$composition//element()中的$eval
让$el1:=(对于$eval//element()中的$el1_
其中,$el1_in_eval/@archetype_node_id='at0002'
返回$el1(在评估中),
$el2:=(对于$eval//element()中的$el2_
其中,$el2_in_eval/@archetype_node_id='at0003'
返回$el2(评估中)
其中$eval/@archetype\u node\u id='openEHR-EVALUATION.goal.v1'
和
(1美元)
和
存在($el2)
)
返回
{$eval/name/value/string(.)}
{对于$eval//element()中的$element1
其中$element1/@archetype\u node\u id='at0002'
返回$element1}
{对于$eval//element()中的$element2
其中$element2/@archetype\u node\u id='at0003'
返回$element2}
}
}
基本上,我使用let语句强制执行父/子关系,并使用return获取let对应匹配的值,这反过来也可以在树上执行相同的操作
如果树是二叉搜索树,则使用XQuery实现。见此帖:
这可能太晚了,没有用了。。。但是看起来您是在已经用抽象树定义的具体树之上实现抽象树。直接使用元素树,而不是用XML元素实现树
看起来您的用例正在查询“原型”openEHR数据 请随意查看一下使用xQuery处理与您的用例类似的请求的开放源代码,但是数据建模有点不同 例如,在论文中,您可以找到一个查询示例,该示例返回所有记录ID,这些记录ID具有组织学检查结果,指示2006-01-01和2006-05-01之间的肿瘤病变 在AQL(原型查询语言)中,它表示为
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'`
选择e/ehr\u id/value作为ehr\u id
来自Ehr e
包含版本v
包含成分c[openEHR成分.组织学检查.v1]
包含观察obs[openEHR-观察。组织学检查结果。v1]
其中(存在obs/数据[at0001]/事件[at0002]/数据[at0003]/项目[at0085]/项目[at0033]/项目[at0034]
或
存在obs/数据[at0001]/事件[at0002]/数据[at0003]/项目[at0085]/项目[at0033]/项目[at0035])
和c/context/start_time/value>='2006-01-01T00:00:00000+01:00'
和c/context/start_time/value<'2006-05-01T00:00:00000+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>
声明命名空间v1=”http://schemas.openehr.org/v1";
声明默认元素名称空间“http://schemas.openehr.org/v1";
声明命名空间xsi