需要帮助重写XQuery以避免MarkLogic中扩展的树缓存完全错误

时间:2014-04-11 15:08:11

标签: caching xquery marklogic

我是XQuery和MarkLogic的新手。 我正在尝试更新MarkLogic中的文档并获取扩展树缓存完整错误。 为了完成工作,我增加了扩展树缓存,但不建议这样做。 我想调整此查询,以便它不需要同时缓存尽可能多的XML。

这是我的查询enter image description here

我已将我的查询上传为图片,因为当我将其粘贴到编辑器上时它并不那么漂亮。如果有人知道更好的方法请建议。

提前致谢。

2 个答案:

答案 0 :(得分:5)

通过执行一次选择太多XML节点的查询,可能会导致扩展树缓存错误。在您的示例中,这可能是罪魁祸首:/tx:AttVal[tx:AttributeName/text()=$attributeName]

调用text()可能是您问题的根源(text()可能不是您的意思 - 请参阅this blog),导致MarkLogic在所有这些节点上评估该功能,通过简单地使用/tx:AttVal[tx:AttributeName=$attributeName],它可以解决您的问题。

接下来,我会考虑在/tx:AttVal/tx:AttributeName上添加路径范围索引,并使用cts:searchcts:path-range-query查询这些节点。这将比没有范围索引的XPath快得多。也可以将XPath与范围索引一起使用:MarkLogic将自动优化XPath表达式以使用范围索引;但是,可能有理由不正确地优化表达式,并且您希望使用xdmp:plan进行检查。

另请注意,MarkLogic中XML的一般最佳实践建议是使用“语义XML”。例如,当您表示属性时,请使用属性:<some-node AttributeName=AttVal>。 MarkLogic的索引针对语义XML设计进行了优化。但是,如果您没有选项但可以使用XML,那么那就是为此设计的路径范围索引。

答案 1 :(得分:3)

我刚刚解决了这个问题。我做了两件事

  • 我将node-replace和node-insert类型调用(即任何将XML结构修改为单独模块的调用,然后使用xdmp:invoke调用该模块,传入所需的任何参数,像这样

    让$ update:= xdmp:invoke(&#34; /app/lib/update-attribute-node.xqy",   (xs:QName(&#34; newValue&#34;),$ new),   {xdmp:模块数据库()})

这样做的原因是对xdmp:invoke的调用发生在它自己的事务中,一旦完成,内存就被清除了。如果你不这样做,那么每次调用更新或插入函数时,它都不会实际执行写操作,直到单个事务结束,这意味着你的内存会很快填满。

  • 任何时候我需要循环遍历MarkLogic中的路径(或文档或其他任何名称 - 我只使用MarkLogic几天)并且有很多我处理它们只有少数几个像下面一样。我想出了一种精心设计的跳过方式,一次只能获取一批文件,但你可以通过多种方式完成。

    let $ whatever:= xdmp:directory(&#34; / whatever /&#34;)[$ start to $ end]

我还将它放入一个单独的模块中,以便立即处理,而不是在单个事务中处理。

将所有昂贵的调用放入单独的模块中,一次只获取大数据集的子集,这有助于我解决扩展的树缓存完全错误。