XQuery基于xml结构创建where子句,作为一种动态where子句

XQuery基于xml结构创建where子句,作为一种动态where子句,xquery,marklogic,Xquery,Marklogic,这是关于XQuery的——我使用MarkLogic作为数据库 我的数据如下例所示: <instrument name="myTest1" id="test1"> <daten> <daily> <day date="2016-02-05"> <screener> <column name="i1">

这是关于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>
我想基于XML结构生成这种where子句

我对MarkLogic内置的cts:search函数和它周围的很多东西做了一些研究,但它似乎是为了其他东西(更多的用户交互搜索)


如果你给我一个提示,告诉我正确的方向,如果我想要的是可能的,我将非常感激。谢谢

是的,这可以通过编程实现。如果您想检查一个元素是否满足序列中每个项目的测试,那么
every。。。我想到了满足
结构。因此,在这种情况下,它可能是:

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
。我假设
修饰符
元素应该修改相等的构造。因此,我们首先检查元素是否满足相等条件,然后检查
修饰符
元素是否等于
。当然,应用同样的思想也可以用于实现其他修饰符。

doc()/instrument XPath要求每个文档都有一个instrument元素,然后过滤这些文档

在可能的情况下,在MarkLogic中,通常最好对文档进行建模,以便使用索引检索尽可能少的文档。通常最好使用cts:search()而不是XPath来生成序列,以便直接使用索引

在此情况下,您可以考虑使用name属性的值作为元素,而不是泛型“列”。然后,可以生成一个CTS:元素查询,它与包含与名称中的值匹配的CTS:EngultValk查询相匹配。


希望这能有所帮助,

哇,这太棒了。我不知道这个构造。老实说,我现在对XQuery还不熟悉一周左右。太神奇了。感谢您的超快速和有益的回应!这也可以在没有FLWOR的单个XPath表达式中实现:
return doc()/instrument[如果($searchpatterns/pattern/c)中的每个$pattern都满足($equal:=daten/day/day/screener/column[@name=$pattern/name]/*[name()=$pattern/element]=$pattern/value return if($pattern/modifier=“not”),那么就不($equal)else$equal)]
谢谢您的建议。我还没有完全理解cts:函数是如何工作的,但我会考虑这一点。我有大约250个仪器文档,这个数字不会增加,因此目前性能不是一个真正的问题,它只供我个人使用。有了250个文档的数据集,读取每个查询中的所有文档不会是一个问题。基于XPath的解决方案适合这种情况。
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"
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