Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Marklogic xquery和子元素的高效循环_Xquery_Marklogic - Fatal编程技术网

Marklogic xquery和子元素的高效循环

Marklogic xquery和子元素的高效循环,xquery,marklogic,Xquery,Marklogic,想象一下,如果有一个xml文档以以下格式存储在Marklogic中: <document> <id>DocumentID</id> <questions> <question_item> <question>question1</question> <answer>answer1</answer> &l

想象一下,如果有一个xml文档以以下格式存储在Marklogic中:

<document>
   <id>DocumentID</id>
   <questions>
       <question_item>
            <question>question1</question>
            <answer>answer1</answer>
       </question_item>
       <question_item>
            <important>high</important>
            <question>question2</question>
            <answer>answer2</answer2>
       <question_item>
</document>

这似乎有效,而且速度相当快。然而,我通常发现for循环并不是在xquery中工作的最快方式。解决方案似乎是一种相对麻烦的方法。有没有更好的方法可以一开始只返回“重要”节点,然后仍然可以访问主文档元素?

我个人认为条件逻辑比循环更麻烦,但我认为可以删除每个节点中的一个以实现更简单的查询。您可以简单地将它们分配给一个变量,从而允许您引用它们,而不是循环遍历第一个文档序列。然后在循环中,使用谓词将
question\u项
约束到那些具有
重要
元素的项,从而消除了对条件项的需要:

let $documents := cts:search(/document,
  cts:element-query(xs:QName("important"), cts:and-query(())
  ), "unfiltered" , 0.0)
for $y in $documents/questions/question_item[important]
return fn:concat($x/id,'|',
  $y/question,'|',
  $y/answer,
  $y/important)

与代码示例一样,最佳方法是首先基于索引匹配文档,然后从匹配的文档中提取值。带有非redundent XPath的FLWOR表达式是从文档中提取值的有效方法

一个可能的改进是在文档建模中采用更细粒度的方法:即,将每个问题项放在单独的文档中。这样,搜索将只检索重要的问题项

如果文件很大,这种变化将变得很重要。为了获得最佳性能,您可以将范围索引放在问题、答案和重要元素上,并直接从索引中为每个问题项获取一个元组

但是,如果问题项的特定列表通常一起检索和更新,则会反对将每个问题拆分为单独的文档


希望这能有所帮助,

终于开始尝试这个。您是对的,约束问题项[重要]更好。然而,虽然您已经删除了“for x$in”,但您的解决方案仍然在结果中引用了$x/id,这是无法预测的。我试着只放入$documents/id,但错误表明它放入的是整个结果集,而不是当前元素。简而言之,仍然没有看到如何在不使用$x的情况下从$y循环中引用主文档元素。我是不是遗漏了一些明显的东西?实际上,我们曾经将每个问题存储为单独的文档。这确实使上面的一些操作变得更容易,但正如您所提到的,也使数据的组织在其他方面更加困难。
let $documents := cts:search(/document,
  cts:element-query(xs:QName("important"), cts:and-query(())
  ), "unfiltered" , 0.0)
for $y in $documents/questions/question_item[important]
return fn:concat($x/id,'|',
  $y/question,'|',
  $y/answer,
  $y/important)