这是关于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>
我有很多乐器,每一个都在每日元素中有一个条目,而在screener中,可以有manz列,所有列都有不同的名称。一些筛选器包含的列数多于其他筛选器。每列可以包含一个value元素,一个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的研究:搜索功能及其周围的很多东西,但它似乎是用于其他东西(更多用户交互式搜索)
如果你有一个暗示指向我正确的方向,如果我想要的甚至可能,我会非常感激。谢谢!
答案 0 :(得分:2)
是的,这可以通过编程方式实现。如果要检查元素是否满足序列中每个项目的测试,则会想到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
元素应该修改相等的构造。因此,我们首先检查元素是否满足相等条件,然后检查modifier
元素是否等于not
。当然,应用相同的想法也可以用来实现其他修饰符。
答案 1 :(得分:2)
doc()/ instrument XPath要求每个文档都有一个instrument元素,然后过滤这些文档。
在可能的情况下,MarkLogic通常会更好地对文档建模,以便您可以使用索引来检索尽可能少的文档。通常最好使用cts:search()而不是XPath来生成序列,以便直接使用索引。
在这种情况下,您可以考虑使用name属性的值作为元素而不是通用“列”。然后,您可以生成一个cts:element-query,该查询匹配包含与名称中的值匹配的cts:element-value-query的名称。
希望有帮助,