0

当我确定数据存在于 Marklogic 中时,我遇到了一个奇怪的问题,即什么应该是简单的 xpath 不返回数据。我可以通过更通用的 xpath 看到有问题的数据,但没有具体得到它。

有效的xpath:

/log:record[log:changes/log:change/@field = "moduleCodes"]
=> a long sequence of log:record elements with "moduleCodes" field changes

xpath 不:

/log:record/log:changes/log:change[@field = "moduleCodes"]
=> empty sequence

(我已经省略了log命名空间定义的简洁性。)

为了弄清楚发生了什么,我从第一个工作的 xpath 开始,并以此为基础:

/log:record[log:changes/log:change/@field = "moduleCodes"]/log:changes/log:change
=> sequence of log:change elements including some with @field = "moduleCodes"
/log:record[log:changes/log:change/@field = "moduleCodes"]/log:changes/log:change[@field]
=> sequence of log:change elements including some with @field = "moduleCodes"
/log:record[log:changes/log:change/@field = "moduleCodes"]/log:changes/log:change[@field = "moduleCodes"]
=> empty sequence

我误解了一些基本的东西吗?log:change当其他一切都按我预期的那样工作时,我看不出为什么将谓词放在 上的 xpath会返回一个空序列。这让我感觉 Marklogic 不知何故感到困惑,但我想确保在我开始这样说话之前,不仅仅是我错过了 xpath 的微妙之处。

我只是尝试了具有不同字段名称的路径。它可以像我期望的那样与(至少一些)其他值一起工作。

我刚刚重启了 ML 集群;没变。


编辑:

上面的所有 xpath 在 Oxygen 中都可以正常工作,所以似乎只有 ML 表现得像这样。我尝试添加fn:doc()到所有路径的前面,以防万一,但这没有任何区别。

这是我认为应该匹配所有 xpath 的(匿名)记录:

<log:record id="00000001" date="2013-04-14T01:42:02.922+01:00" type="change" xmlns:log="some/namespace/definition">
  <log:head>
     <some-header-info/>
  </log:head>
  <log:changes>
    <log:change field="dateModified">
      <log:old-value>2012-11-06T00:00:00.0000000</log:old-value>
      <log:new-value>2013-03-20T00:00:00.0000000</log:new-value>
    </log:change>
    <log:change field="moduleCodes">
      <log:old-value>
        <log:moduleCodes>
          <log:moduleCodes-value code="AAA"/>
        </log:moduleCodes>
      </log:old-value>
      <log:new-value>
        <log:moduleCodes>
          <log:moduleCodes-value code="AAA"/>
          <log:moduleCodes-value code="BBB"/>
        </log:moduleCodes>
      </log:new-value>
    </log:change>
  </log:changes>
</log:record>
4

1 回答 1

2

As best I can recreate your test with 6.0-2.3, this works for me.

When debugging database queries, one useful technique is to move things in memory. If it still doesn't work, this throws suspicion on the database query. When I try that using 6.0-2.3, the results seem to be correct.

declare namespace log="some/namespace/definition" ;
document {
<log:record id="00000001" date="2013-04-14T01:42:02.922+01:00" type="change" xmlns:log="some/namespace/definition">
  <log:head>
     <some-header-info/>
  </log:head>
  <log:changes>
    <log:change field="dateModified">
      <log:old-value>2012-11-06T00:00:00.0000000</log:old-value>
      <log:new-value>2013-03-20T00:00:00.0000000</log:new-value>
    </log:change>
    <log:change field="moduleCodes">
      <log:old-value>
        <log:moduleCodes>
          <log:moduleCodes-value code="AAA"/>
        </log:moduleCodes>
      </log:old-value>
      <log:new-value>
        <log:moduleCodes>
          <log:moduleCodes-value code="AAA"/>
          <log:moduleCodes-value code="BBB"/>
        </log:moduleCodes>
      </log:new-value>
    </log:change>
  </log:changes>
</log:record> }
/log:record[log:changes/log:change/@field = "moduleCodes"]/xdmp:path(.)
=>
/log:record

declare namespace log="some/namespace/definition" ;
document {
<log:record id="00000001" date="2013-04-14T01:42:02.922+01:00" type="change" xmlns:log="some/namespace/definition">
  <log:head>
     <some-header-info/>
  </log:head>
  <log:changes>
    <log:change field="dateModified">
      <log:old-value>2012-11-06T00:00:00.0000000</log:old-value>
      <log:new-value>2013-03-20T00:00:00.0000000</log:new-value>
    </log:change>
    <log:change field="moduleCodes">
      <log:old-value>
        <log:moduleCodes>
          <log:moduleCodes-value code="AAA"/>
        </log:moduleCodes>
      </log:old-value>
      <log:new-value>
        <log:moduleCodes>
          <log:moduleCodes-value code="AAA"/>
          <log:moduleCodes-value code="BBB"/>
        </log:moduleCodes>
      </log:new-value>
    </log:change>
  </log:changes>
</log:record> }
/log:record/log:changes/log:change[@field = "moduleCodes"]/xdmp:path(.)
=>
/log:record/log:changes/log:change[2]

So the implication is that the problem is in the index or the way the index is queried. You can try to debug that using xdmp:query-trace(true()) at the start of your query. For example:

declare namespace log="some/namespace/definition" ;
xdmp:query-trace(true()),
/log:record[log:changes/log:change/@field = "moduleCodes"]/xdmp:describe(.),
/log:record/log:changes/log:change[@field = "moduleCodes"]/xdmp:describe(.)

With 6.0-2.3 these both return the expected results for me.

fn:doc("test")/log:record
fn:doc("test")/log:record/log:changes/log:change[2]

Here are the traces, from the ErrorLog.txt file:

Analyzing path: fn:collection()/log:record[log:changes/log:change/@field = "moduleCodes"]/xdmp:describe(.)
Step 1 is searchable: fn:collection()
Step 2 is searchable: log:record[log:changes/log:change/@field = "moduleCodes"]
Step 3 is unsearchable: xdmp:describe(.)
First 2 steps of path are searchable: fn:collection()/log:record[log:changes/log:change/@field = "moduleCodes"]
Gathering constraints.
 Comparison contributed hash value constraint: log:change/@field = "moduleCodes"
Step 2 predicate 1 contributed 3 constraints: log:changes/log:change/@field = "moduleCodes"
 Comparison contributed hash value constraint: log:change/@field = "moduleCodes"
Step 2 predicate 1 contributed 1 constraint: log:changes/log:change/@field = "moduleCodes"
Step 2 contributed 4 constraints: log:record[log:changes/log:change/@field = "moduleCodes"]
Executing search.
Selected 1 fragment to filter
 xdmp:eval("declare namespace log=&quot;some/namespace/definition&quot; ;&#1...", (), <options xmlns="xdmp:eval"><database>598453498912235799</database><root>/tmp</root><isolati...</options>)
 Analyzing path: fn:collection()/log:record/log:changes/log:change[@field = "moduleCodes"]/xdmp:describe(.)
 Step 1 is searchable: fn:collection()
 Step 2 is searchable: log:record
 Step 3 is searchable: log:changes
 Step 4 is searchable: log:change[@field = "moduleCodes"]
 Step 5 is unsearchable: xdmp:describe(.)
 First 4 steps of path are searchable: fn:collection()/log:record/log:changes/log:change[@field = "moduleCodes"]
 Gathering constraints.
Step 2 contributed 1 constraint: log:record
 Comparison contributed hash value constraint: log:change/@field = "moduleCodes"
 Step 4 predicate 1 contributed 1 constraint: @field = "moduleCodes"
 Step 4 contributed 1 constraint: log:change[@field = "moduleCodes"]
 Comparison contributed hash value constraint: log:change/@field = "moduleCodes"
 Step 4 predicate 1 contributed 1 constraint: @field = "moduleCodes"
 Comparison contributed hash value constraint: log:change/@field = "moduleCodes"
 Step 4 predicate 1 contributed 1 constraint: @field = "moduleCodes"
 Step 4 contributed 1 constraint: log:change[@field = "moduleCodes"]
 Step 3 contributed 1 constraint: log:changes
 Executing search.
 Selected 1 fragment to filter
于 2013-04-19T16:52:55.053 回答