这个xpath有什么问题,还是Marklogic行为不端?

时间:2013-04-19 12:06:15

标签: xpath xquery marklogic

我有一个奇怪的问题,当我确定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>

1 个答案:

答案 0 :(得分:2)

最好我可以用6.0-2.3重新创建你的测试,这对我有用。

调试数据库查询时,一种有用的技术是在内存中移动内容。如果它仍然不起作用,则会引发对数据库查询的怀疑。当我尝试使用6.0-2.3时,结果似乎是正确的。

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]

因此暗示问题出在索引或查询索引的方式中。您可以尝试在查询开始时使用xdmp:query-trace(true())进行调试。例如:

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(.)

对于6.0-2.3,这些都会为我返回预期的结果。

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

以下是来自ErrorLog.txt文件的跟踪:

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