XQuery 基于 xml 结构创建 where 子句作为一种动态 where 子句
XQuery Create where clause based on xml structure as a kind of dynamic where clause
这是关于 XQuery - 我使用 MarkLogic 作为数据库。
我有如下示例中的数据:
<instrument name="myTest1" id="test1">
<daten>
<daily>
<day date="2016-02-05">
<screener>
<column name="i1">
<value>1</value>
<bg>red</bg>
</column>
<column name="i2">
<value>1</value>
<fg>lime</bg>
</column>
<column name="i4">
<fg>black</bg>
</column>
</screener>
</day>
</daily>
</daten>
</instrument>
我有很多 instruments,每个 instruments 在 daily element 和 screener 里面都有一个 manz columns,都有不同的名字。一些筛选器包含的列比其他筛选器多。每列可以包含一个值元素、一个 bg 元素和一个 fg 元素。
我想搜索满足特定条件的工具,即哪些列的子项具有特定值。示例:我想要一个所有工具的序列,在给定的一天,第 i1 列的值为 1,第 i2 列的 fg 为黑色
由于我有许多不同的条件,我不想在 XQuery where 子句中对它们进行硬编码。我这样做了几次并且它有效,但是代码有很多重复并且很难维护。
我的问题是,是否有可能以编程方式在 FLOWR 语句中构建 where 子句,也就是说,基于另一个 xml 结构,它可能如下所示:
<searchpatterns>
<pattern name="test1">
<c>
<name>i1</name>
<element>value</element>
<value>1</value>
</c>
<c>
<name>i2</name>
<element>fg</element>
<value>red</value>
<modifier>not</modifier>
</c>
</pattern>
</searchpatterns>
这会找到那些仪器,其中筛选器有一个 i1 列,它本身的值为 1,而且它不能有带有红色 fg 的 i2 列。
当我以正常方式查询时,我会这样查询我的日期:
for $res in doc()/instrument
where $res/daten/daily/day[@date="2016-02-05"]/screener/column[@name="i1"]/value/text()="1"
and res/daten/daily/day[@date="2016-02-05"]/screener/column[@name="i2"]/fg/text()!="red"
我想根据 XML 结构生成这种 where 子句。
我对 MarkLogic 内置的 cts:search 函数和它周围的很多东西做了一些研究,但它似乎是为了别的东西(更多的用户交互搜索)
如果你能给我指明正确的方向,如果我想要的是可能的,我将不胜感激it.Thanks!
是的,这可以通过编程方式实现。如果你想检查一个元素是否满足序列中每个项目的测试,every ... satisfies
结构就会浮现在脑海中。所以在这种情况下它可能是:
for $res in doc()/instrument
where every $pattern in $searchpatterns/pattern/c satisfies (
let $equal := $res/daten/daily/day[@date="2016-02-05"]/screener/column[@name = $pattern/name]/*[name() = $pattern/element] = $pattern/value
return if ($pattern/modifier = "not") then not($equal) else $equal
)
return $res
所以每个 $pattern
都会被检查。我假设 modifier
元素应该修改 equal 结构。所以我们首先检查元素是否满足相等条件,然后我们检查 modifier
元素是否等于 not
。当然,应用同样的想法也可以用来实现其他修饰符。
doc()/instrument XPath 请求每个包含 instrument 元素的文档,然后过滤这些文档。
在可能的情况下,通常最好在 MarkLogic 中对文档建模,这样您就可以使用索引来检索尽可能少的文档。通常最好使用 cts:search() 而不是 XPath 来生成序列,这样您就可以直接使用索引。
在这种情况下,您可以考虑使用 name 属性的值作为元素而不是通用的 "column." 然后您可以生成一个 cts:element-query 匹配包含 cts:element-与名称中的值匹配的值查询。
希望对您有所帮助,
这是关于 XQuery - 我使用 MarkLogic 作为数据库。
我有如下示例中的数据:
<instrument name="myTest1" id="test1">
<daten>
<daily>
<day date="2016-02-05">
<screener>
<column name="i1">
<value>1</value>
<bg>red</bg>
</column>
<column name="i2">
<value>1</value>
<fg>lime</bg>
</column>
<column name="i4">
<fg>black</bg>
</column>
</screener>
</day>
</daily>
</daten>
</instrument>
我有很多 instruments,每个 instruments 在 daily element 和 screener 里面都有一个 manz columns,都有不同的名字。一些筛选器包含的列比其他筛选器多。每列可以包含一个值元素、一个 bg 元素和一个 fg 元素。
我想搜索满足特定条件的工具,即哪些列的子项具有特定值。示例:我想要一个所有工具的序列,在给定的一天,第 i1 列的值为 1,第 i2 列的 fg 为黑色
由于我有许多不同的条件,我不想在 XQuery where 子句中对它们进行硬编码。我这样做了几次并且它有效,但是代码有很多重复并且很难维护。
我的问题是,是否有可能以编程方式在 FLOWR 语句中构建 where 子句,也就是说,基于另一个 xml 结构,它可能如下所示:
<searchpatterns>
<pattern name="test1">
<c>
<name>i1</name>
<element>value</element>
<value>1</value>
</c>
<c>
<name>i2</name>
<element>fg</element>
<value>red</value>
<modifier>not</modifier>
</c>
</pattern>
</searchpatterns>
这会找到那些仪器,其中筛选器有一个 i1 列,它本身的值为 1,而且它不能有带有红色 fg 的 i2 列。
当我以正常方式查询时,我会这样查询我的日期:
for $res in doc()/instrument
where $res/daten/daily/day[@date="2016-02-05"]/screener/column[@name="i1"]/value/text()="1"
and res/daten/daily/day[@date="2016-02-05"]/screener/column[@name="i2"]/fg/text()!="red"
我想根据 XML 结构生成这种 where 子句。
我对 MarkLogic 内置的 cts:search 函数和它周围的很多东西做了一些研究,但它似乎是为了别的东西(更多的用户交互搜索)
如果你能给我指明正确的方向,如果我想要的是可能的,我将不胜感激it.Thanks!
是的,这可以通过编程方式实现。如果你想检查一个元素是否满足序列中每个项目的测试,every ... satisfies
结构就会浮现在脑海中。所以在这种情况下它可能是:
for $res in doc()/instrument
where every $pattern in $searchpatterns/pattern/c satisfies (
let $equal := $res/daten/daily/day[@date="2016-02-05"]/screener/column[@name = $pattern/name]/*[name() = $pattern/element] = $pattern/value
return if ($pattern/modifier = "not") then not($equal) else $equal
)
return $res
所以每个 $pattern
都会被检查。我假设 modifier
元素应该修改 equal 结构。所以我们首先检查元素是否满足相等条件,然后我们检查 modifier
元素是否等于 not
。当然,应用同样的想法也可以用来实现其他修饰符。
doc()/instrument XPath 请求每个包含 instrument 元素的文档,然后过滤这些文档。
在可能的情况下,通常最好在 MarkLogic 中对文档建模,这样您就可以使用索引来检索尽可能少的文档。通常最好使用 cts:search() 而不是 XPath 来生成序列,这样您就可以直接使用索引。
在这种情况下,您可以考虑使用 name 属性的值作为元素而不是通用的 "column." 然后您可以生成一个 cts:element-query 匹配包含 cts:element-与名称中的值匹配的值查询。
希望对您有所帮助,