使用XPath谓词优化XQuery interogation

时间:2018-03-15 20:03:22

标签: xpath xquery exist-db

所以,我正在优化我从SQL中继承的查询,与之前在sql中工作的方式相比,我遇到了一些性能问题。

基本上,我的php脚本发送2到5组两个(数字)值。

这些必须与我的集合元素中的id和doc进行比较。当然,谓词中的元素越少,查询越快 我的for谓词现在看起来像这样:

for $p in collection("/db/col1")//set1/page[(id eq val1 and doc eq altval1) or (id eq val2 and doc eq altval2) or (id eq val3 and doc eq altval3) or (id eq val4 and doc eq altval4) or (id eq val5 and doc eq altval5)]

我需要以某种方式编写一个根据值的数量而变化的谓词。我尝试编写一个函数来编写条件并在谓词中调用它,具体取决于传递了多少个值,但这似乎不起作用。

如果有人知道解决方法,我真的很感激。

编辑:删除了代码中的拼写错误。

3 个答案:

答案 0 :(得分:5)

如果$val$altval是两个值序列,那么您可以编写通用谓词

SOMETHING[some $i in 1 to count($val) satisfies (id=$val[$i] and doc=$altval[$i]] 

但我不知道它会有多好。

答案 1 :(得分:4)

如果你想在谓词中使用一个函数,那么下面这样的东西可能对你有用:

xquery version "3.1";

declare variable $local:criteria := array {
  ("val1", "altval1"),
  ("val2", "altval2"),
  ("val3", "altval3"),
  ("val4", "altval4"),
  ("val5", "altval5")
};

declare function local:match($id, $doc) as xs:boolean {
  array:size(
    array:filter($local:criteria, function($x) {
      $id eq $x[1] and $doc eq $x[2]
    })
  ) eq 1  
};

collection("/db/col1")//set1//page[local:match(id, doc)]

注意 - 我没有测试过上面的表现。

也许值得一提的是,eXist-db中的祖先查找由于其DLN node numbering而非常快。因此,如果//set1//page比说//page[ancestor::set1]慢,则可能值得测试。

答案 2 :(得分:0)

我赞同这两个答案,因为他们都完成了工作,我可以清楚地看到改进。我不想选择一个而不是另一个,因为我认为此时更多的是品味问题。

就我而言,我找到了第三个,特别是对于这种情况更快。在不利方面,它非常繁琐,不优雅且非常具体。此外,虽然您的答案可以适应几个类似的问题,但这个问题仅适用于您触发“问题”的情况。外部的XQuery脚本。所以这就是:

我实际上制作了五个不同的xql脚本,一个处理1对值,一个处理前两对,使用前三对等。

因此脚本将包含:

  for $p in collection("/db/col1")//set1/page[id eq val1 and doc1 eq altval1]

在脚本五中,你会发现类似原文的内容:

 for $p in collection("/db/col1")//set1/page[(id eq val1 and doc eq altval1) or (id eq val2 and doc eq altval2) or (id eq val3 and doc eq altval3) or (id eq val4 and doc eq altval4) or (id eq val5 and doc eq altval5)]

然后我从我的PHP脚本中调用它们,具体取决于我需要发送的参数数量。我不会尝试将其扩展到超过五对,但目前它已完成工作。