and-query 匹配一个属性值和一个子元素值

and-query to match an attribute value and a subelement value

我的文档包含如下结构:

<Reviews>
    <Review complete="false">
        <StartDate>2019-03-05T06:00:00Z</StartDate>
        <EndDate>2019-03-12T05:00:00Z</EndDate>
        <Reviewers>
            <Reviewer userName="jdoe">
                <ReviewStatus>Completed</ReviewStatus>
            </Reviewer>
        </Reviewers>
    </Review>
    <Review complete="false">
        <StartDate>2019-03-06T06:00:00Z</StartDate>
        <EndDate>2019-03-13T05:00:00Z</EndDate>
        <Reviewers>
            <Reviewer userName="jsmith">
                <ReviewStatus>Pending</ReviewStatus>
            </Reviewer>
            <Reviewer userName="jdoe">
                <ReviewStatus>Completed</ReviewStatus>
            </Reviewer>
        </Reviewers>
   </Review>
</Reviews>

使用 MarkLogic XQuery,我想搜索具有 jsmith 的 Reviewer 元素并且具有 his ReviewStatus=Completed 的文档。也就是说,我不想在我的结果中看到上面的这个示例,因为 jsmith 的 ReviewStatus 未完成。 我尝试了几种不同的查询类型,其中 cts:and-query() 使用属性值、元素词甚至路径范围查询的组合。但是我还没有弄清楚如何只找到那些包含 Reviewer 元素的文档,其中 userName 属性值与 "jsmith" 匹配并且 ReviewStatus 子元素值与同一 Reviewer 元素中的 "Completed" 匹配。有人可以为此建议一种方法吗?

您正在查找范围查询,例如 cts:element-query。它允许您为子查询选择一个联合祖先。这里有一些代码展示了它是如何工作的:

let $search-name := "jsmith"
let $search-status := "Completed"

let $xml := <Reviews>
    <Review complete="false">
        <StartDate>2019-03-05T06:00:00Z</StartDate>
        <EndDate>2019-03-12T05:00:00Z</EndDate>
        <Reviewers>
            <Reviewer userName="jsmith">
                <ReviewStatus>Completed</ReviewStatus>
            </Reviewer>
            <Reviewer userName="jdoe">
                <ReviewStatus>Pending</ReviewStatus>
            </Reviewer>
        </Reviewers>
    </Review>
    <Review complete="false">
        <StartDate>2019-03-06T06:00:00Z</StartDate>
        <EndDate>2019-03-13T05:00:00Z</EndDate>
        <Reviewers>
            <Reviewer userName="jsmith">
                <ReviewStatus>Pending</ReviewStatus>
            </Reviewer>
            <Reviewer userName="jdoe">
                <ReviewStatus>Completed</ReviewStatus>
            </Reviewer>
        </Reviewers>
   </Review>
</Reviews>
for $rev in $xml//Reviewer
where cts:contains(
  $rev,
  cts:element-query(
    xs:QName("Reviewer"),
    cts:and-query((
      cts:element-attribute-value-query(xs:QName("Reviewer"), xs:QName("userName"), $search-name),
      cts:element-value-query(xs:QName("ReviewStatus"), $search-status)
    ))
  )
)
return $rev

请注意,如果您需要未过滤搜索的准确结果,则需要启用位置索引。

HTH!