无法找到 xdmp:plan 个结果文档

Unable to find xdmp:plan result documentation

我很难找到有关 xdmp:plan 输出含义的详细信息。

有一个像这样的简单查询:

xdmp:plan(cts:search(doc(), cts:element-value-query(xs:QName("description"), "some text")))

导致相当长的执行计划:

<qry:query-plan xmlns:qry="http://marklogic.com/cts/query">
<qry:expr-trace>...</qry:expr-trace>
...
<qry:partial-plan>
  <qry:term-query weight="1">
      <qry:key>16037778974159125508</qry:key>
      <qry:annotation>element(description,value("some","text"))</qry:annotation>
  </qry:term-query>
</qry:partial-plan>
...
<qry:ordering></qry:ordering>
<qry:final-plan>
  <qry:and-query>
    <qry:term-query weight="1">
      <qry:key>16037778974159125508</qry:key>
      <qry:annotation>element(description,value("some","text"))</qry:annotation>
    </qry:term-query>
  </qry:and-query>
</qry:final-plan>
<qry:info-trace>Selected 0 fragments to filter</qry:info-trace>
<qry:result estimate="0"></qry:result>
</qry:query-plan>

文档中唯一提到 xdmp:plan 的部分是其 documentation 本身。除此之外,我找不到其他任何东西。我想要一些关于什么的细节。 qry:keyqry:annotation 真的很意思。

我是否缺少描述 xdmp:plan 可能输出的任何文档。由于这是了解查询性能的一个非常有价值的工具,我希望它有很好的文档记录。


编辑:我发现的这个 marklogic blog post 给出了一些如何解释查询计划的示例。

不过,我觉得博客 post 应该 是此工具的 唯一合理的文档

我还有一些问题:

有时我可以在查询计划中找到这个:

<qry:elem-word-trace text="computer" elem-name="title" elem-uri="">
   <qry:key>10975994818398622042</qry:key>
</qry:elem-word-trace>

这有什么原因吗?为什么步骤 2 谓词 1 贡献相同的 partial-plan 两次?

<qry:info-trace>Step 2 predicate 1 contributed 1 constraint: id = 1</qry:info-trace>
<qry:partial-plan xmlns:qry="...">...</qry:partial-plan>
<qry:info-trace>Step 2 predicate 1 contributed 1 constraint: id = 1</qry:info-trace>
<qry:partial-plan xmlns:qry="...">...</qry:partial-plan>

经过更多的搜索和阅读,我决定总结一下我的发现。

注意:如果不使用分片,每次使用"fragment"都可以和"document"相提并论。

部分计划与完整计划

A partial-plan 只是显示了计划的增量部分,似乎主要仅供参考。

另一方面,full-plan 是请求如何发送到索引,因此大多数时候是有趣的部分。

已选择 x 个片段

documentation of query-traceinfo-trace 消息的含义提供了一些见解:

过滤 查询结果 info-trace 描述了从查询处理的索引解析阶段 return 编辑了多少候选片段引用:

xdmp:plan(cts:search(doc(), cts:element-word-query(xs:QName("title"), "computer")))
=> ...
<qry:info-trace>Selected 2 fragments to filter</qry:info-trace>

A unfiltered 查询记录了相同的消息,但没有 "to filter" 指示未执行第二个过滤步骤:

xdmp:plan(cts:search(doc(), cts:element-word-query(xs:QName("title"), "computer"), ("unfiltered")))
=> ...
<qry:info-trace>Selected 2 fragments</qry:info-trace>

qry:结果

<qry:result estimate="2"></qry:result>

qry:result中的estimate显示了有多少片段与仅使用索引信息的查询匹配。所以这是过滤步骤之前的估计数字,因此可能包含误报。我认为估计的值和上面描述的信息跟踪的日志总是相同的。


不同的注释示例

有一个 element-word-query,只有 word searches 启用(fast element word searches 禁用)returns 这个 final-plan:

xdmp:plan(cts:search(doc(), cts:element-word-query(xs:QName("title"), "computer")))
=> ...
<qry:final-plan>
   <qry:and-query>
      <qry:term-query weight="1">
         <qry:key>13967911917401594192</qry:key>
         <qry:annotation>word("computer")</qry:annotation>
      </qry:term-query>
      <qry:term-query weight="0">
         <qry:key>745773915438417736</qry:key>
         <qry:annotation>element(title)</qry:annotation>
      </qry:term-query>
   </qry:and-query>
</qry:final-plan>

有两个单独的术语查询,一个 word("computer") 和一个 element(title) 意味着它还将 return 包含元素 [=30= 之外的单词 "computer" 的文档].因此,未经过滤的搜索可能 return 误报。

有一个element-word-query同时word searchesfast element word searches启用return这是final-plan:

<qry:final-plan>
   <qry:and-query>
      <qry:term-query weight="1">
         <qry:key>10975994818398622042</qry:key>
         <qry:annotation>element(title,word("computer"))</qry:annotation>
      </qry:term-query>
   </qry:and-query>
</qry:final-plan>

此处annotation表示在title元素内对词"computer"进行组合搜索。此查询可能未经过滤,但在我的案例中仍然 return 没有误报。

更多详细信息在此 blog post


qry:订购

那个 <qry:ordering> 标签表示生成的候选片段引用正在排序。这可以通过 cts:order Constructors in the cts:search 函数之一进行控制。示例:

xdmp:plan(
  cts:search(
    doc(), 
    cts:element-word-query(xs:QName("title"), "computer"), 
    (cts:unordered())
))
=>....
<qry:ordering>
    <qry:unordered></qry:unordered>
</qry:ordering>

如何查看,是否使用了索引

我一直想知道,如何查看是否使用了索引(用于查询执行计划,如全索引扫描)。 最终你可以很容易地判断是否使用了索引:

搜索 <qry:info-trace> 个日志,其中包含 searchable。包含 searchable 的消息是好的,这意味着您的这部分查询可以使用索引执行。如果它包含单词 unsearchable,这可能是一个不好的迹象。

xdmp:plan(//image/id[. = "1"]/..) 的日志消息可能如下所示:

<qry:info-trace>Analyzing path: fn:collection()/descendant::image/id[. = "1"]/..</qry:info-trace>
<qry:info-trace>Step 1 is searchable: fn:collection()</qry:info-trace>
<qry:info-trace>Step 2 is searchable: descendant::image</qry:info-trace>
<qry:info-trace>Step 3 is searchable: id[. = "1"]</qry:info-trace>
<qry:info-trace>Step 4 axis is unsearchable: parent</qry:info-trace>
<qry:info-trace>Step 4 is unsearchable: ..</qry:info-trace>

表示除第4步外的所有部分,/..可以通过索引解析。这可能不是一个坏兆头,具体取决于您的查询。在这种情况下,可以修改查询:

这个稍微修改过的查询可以使用所有的索引 "steps" xdmp:plan(//image[id = "1"]);

<qry:info-trace>Analyzing path: fn:collection()/descendant::image[id = "1"]</qry:info-trace>
<qry:info-trace>Step 1 is searchable: fn:collection()</qry:info-trace>
<qry:info-trace>Step 2 is searchable: descendant::image[id = "1"]</qry:info-trace>
<qry:info-trace>Path is fully searchable.</qry:info-trace>

可以找到更多详细信息 here


如果有人找到更多关于如何解释和使用 xmdp:plan 输出的信息,我很乐意知道。

2018 年 11 月 17 日更新:

发现这个非常有趣 video Mary Holstege 在其中谈论 MarkLogic 搜索和索引。这涵盖了我的很多问题,我真的可以推荐它。

我还要补充一点,如果你在最终计划中看到一个没有注释的术语,那就是一个错误,你应该报告它。