Marklogic查询基于同一元素的多个属性的值

时间:2014-09-02 13:00:20

标签: marklogic

我有以下xmls:

sample1.xml      <root> <subjectInfo> <subject id="001"/> <subject id="002" role="cross"/> </subjectInfo> </root>

sample2.xml      <root> <subjectInfo> <subject id="002"/> <subject id="001" role="cross"/> </subjectInfo> </root>

我正在搜索id subject的{​​{1}}属性值为“001”但role(如果它在那里)的相同subject元素的文档不是“交叉”。所以,在我的示例中,结果应包含sample1.xml而不是sample2.xml

我认为以下查询可以完成这项工作:

<code>
cts:search(/root,
        cts:near-query((
           cts:element-attribute-value-query(xs:QName("subject"),xs:QName("id"),"001"),
           cts:not-query(cts:element-attribute-value-query(xs:QName("subject"),xs:QName("role"),"cross"))),0)

           )
</code>

但它没有(返回一个空序列)。请给我一个。

2 个答案:

答案 0 :(得分:4)

正如@wst所说,cts:not-query匹配这两个文件。 cts:*个查询匹配文档片段,而不是子树。您可以通过将cts:element-attribute-value-query构造函数嵌套在cts:element-query内来匹配条件的相反情况。这将匹配sample2.xml

cts:search(/root,
  cts:element-query(xs:QName("subject"),
    cts:and-query((
      cts:element-attribute-value-query(xs:QName("subject"),xs:QName("id"),"001"),
      cts:element-attribute-value-query(xs:QName("subject"),xs:QName("role"),"cross")))))

也许您可以调整查询要求,这样就足够了。如果没有,您可以使用except运算符排除与此搜索匹配的文档。这将匹配sample1.xml

cts:search(/root,
  cts:element-attribute-value-query(xs:QName("subject"),xs:QName("id"),"001"))

except

cts:search(/root,
  cts:element-query(xs:QName("subject"),
    cts:and-query((
      cts:element-attribute-value-query(xs:QName("subject"),xs:QName("id"),"001"),
      cts:element-attribute-value-query(xs:QName("subject"),xs:QName("role"),"cross")))))

如果您的文档具有唯一标识符,则可以添加范围索引并使用其中一个cts:*-values函数来获取与第二个cts:search匹配的文档的唯一ID,然后使用cts:not-querycts:*-range-query从第一个cts:search中排除文档。

答案 1 :(得分:3)

我认为问题是cts:not-query在两个文档上都匹配,因此将它们从结果集中排除。

这可能还不够,因为它不是仅索引查询,但您可以通过过滤误报来补充cts:search结果:

cts:search(/root,
  cts:element-attribute-value-query(xs:QName("subject"), 
    xs:QName("id"), "001"))[subjectInfo/subject[@id='001' and not(@role='cross')]