我是XQuery和MarkLogic的新手。 我正在尝试更新MarkLogic中的文档并获取扩展树缓存完整错误。 为了完成工作,我增加了扩展树缓存,但不建议这样做。 我想调整此查询,以便它不需要同时缓存尽可能多的XML。
这是我的查询
我已将我的查询上传为图片,因为当我将其粘贴到编辑器上时它并不那么漂亮。如果有人知道更好的方法请建议。
提前致谢。
答案 0 :(得分:5)
通过执行一次选择太多XML节点的查询,可能会导致扩展树缓存错误。在您的示例中,这可能是罪魁祸首:/tx:AttVal[tx:AttributeName/text()=$attributeName]
。
调用text()
可能是您问题的根源(text()
可能不是您的意思 - 请参阅this blog),导致MarkLogic在所有这些节点上评估该功能,通过简单地使用/tx:AttVal[tx:AttributeName=$attributeName]
,它可以解决您的问题。
接下来,我会考虑在/tx:AttVal/tx:AttributeName
上添加路径范围索引,并使用cts:search
和cts: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]
我还将它放入一个单独的模块中,以便立即处理,而不是在单个事务中处理。
将所有昂贵的调用放入单独的模块中,一次只获取大数据集的子集,这有助于我解决扩展的树缓存完全错误。