首页 > 解决方案 > and-query 匹配一个属性值和一个子元素值

问题描述

我有包含以下结构的文档:

<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 元素并且他的ReviewStatus=Completed 的文档。即,我不想在我的结果中看到上面的这个示例,因为 jsmith 的 ReviewStatus 没有完成。我尝试了几种不同的查询类型,其中cts:and-query()使用属性值、元素词甚至路径范围查询的组合。但我还没有想出如何只找到那些包含 Reviewer 元素的文档,其中 userName 属性值与“jsmith”匹配,并且 ReviewStatus 子元素值与同一 Reviewer 元素中的“Completed”匹配。任何人都可以为此提出一种方法吗?

标签: xquerymarklogiccts-search

解决方案


您正在寻找范围查询,例如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

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


推荐阅读