Xquery 扩展的树缓存在marklogic上已满

Xquery 扩展的树缓存在marklogic上已满,xquery,marklogic,Xquery,Marklogic,我在MarkLogic应用程序的查询控制台上运行下面的查询,在此基础上检索与filter query匹配的文档的ID。执行时,我将面临扩展的树缓存已满。 我的问题是: let $a: = cts:search(doc(), cts:element-query(xs:QName("doc__doc_type"), cts:and-query(())) ) for $doc in $a return ($doc//base__unique_id/text()) 如何微调此查询 与此查询匹配的文

我在MarkLogic应用程序的查询控制台上运行下面的查询,在此基础上检索与filter query匹配的文档的ID。执行时,我将面临扩展的树缓存已满。
我的问题是:

let $a: = cts:search(doc(),
  cts:element-query(xs:QName("doc__doc_type"), cts:and-query(()))
)
for $doc in $a
return ($doc//base__unique_id/text())
如何微调此查询

与此查询匹配的文档数为1336967。 配置的树大小为2048MB


我需要帮助微调此查询,使其以页面形式返回值。

您可以通过以下方式对
cts:search
返回的序列进行子排序,从而对
cts:search
的结果进行分页:

let $a := cts:search(doc(), cts:element-query(xs:QName("doc__doc_type"),cts:and-query(())) ) 
let $page1 := $a[1 to 10]
let $page2 := $a[11 to 20]
return $page1
背景

有关详细信息,请参阅关于分页和筛选搜索的

默认情况下,MarkLogic
cts:search
API分两步执行搜索:

  • 直接从索引中识别候选片段(文档)ID。这是在内存中完成的,速度很快。结果可能包含假阳性

  • 候选片段ID从磁盘加载,并根据所有搜索条件进行全面检查,以过滤出误报。这是在内存中完成的,速度很慢

  • 如果您希望加快搜索速度,并且能够容忍误报,则可以跳过第二步,执行未筛选的搜索,专门从索引中解析候选片段:

    let $all-docs := cts:search(doc(), cts:and-query(()), "unfiltered")
    return $all-docs[1 to 10]
    

    您有几个选项可用于优化此查询

    • 最佳选择:假设
      base\uuuuu unique\u id
      实际上是一个唯一的id,您可以在其上放置一个范围索引,并返回查询中的所有现有值。这将是一个更快的查询,也将使用更少的内存,因为您不会打开返回的每个文档
    • 将结果分页。不要一次返回所有结果。在几个查询过程中执行此操作。如果您只是生成一个所有结果的列表,您还可以查看,以帮助您以可伸缩的方式完成这项工作
    • 如果这样做有意义,那么您可能需要考虑根据文档类型为数据分配名称空间。这将产生更小的术语列表(提高性能),并可能简化许多查询表达式
    • 如果您没有遵循我的第一个建议,那么可以尝试使用绝对XPath表达式,而不是现在使用的相对XPath表达式
    • 如果您没有遵循我的第一条建议,您可以将您的
      cts:search
      设置为未筛选。这将有助于加快生成结果的速度,但可能无法修复扩展树缓存错误

    如果您无法轻松创建索引,并且希望避免在翻阅所有文档时破坏扩展的树缓存

    它可能不是最快的(您可能需要提高超时限制),但您可以通过消除FLWOR语句并使用不需要缓冲任何文档或值的表达式来避免XDMP-EXPTREECHACHEFULL错误,例如:

    cts:search(doc(),
      cts:element-query(xs:QName("doc__doc_type"), cts:and-query(()))
    )//base__unique_id/text()
    

    使用“未过滤”选项。这将在索引解析步骤不允许筛选文档的情况下停止搜索。过滤文档意味着逐个解压缩文档片段以搜索将使用扩展树缓存的术语。考虑到结果的数量,最好使用此选项。

    在他检查元素是否存在,而不是元素所在位置时,您实际上应该能够不经筛选地运行此查询,而不会产生任何肯定结果。对于更复杂的查询,可以启用位置索引以消除误报。但是,使搜索未过滤对扩展的树缓存没有帮助,因为这是通过for循环将每个文档加载到内存中造成的。感谢您的澄清。如果我理解正确,询问者可以通过未经过滤的搜索加快搜索速度,而不会出现任何误报?当然,他们仍然需要对结果进行子集划分,以避免将太多片段拉入内存,从而解决扩展树缓存问题。正确。是否收到误报取决于正在运行的查询以及可用于解决该问题的索引。对于询问者的查询,不应该有任何未经过滤的误报。范围索引将相当昂贵,因为每个值都是唯一的,因此也不会从cts中获益:返回不同值的值。不过,范围索引可能会更快,因为上面的索引确实会触及搜索结果集中的每个文档,这可能会在搜索过程中创建许多读锁。不过,这仍然是一个很好的答案,因为搜索结果捕获在一个变量中是缓存错误的罪魁祸首。。