Xquery 和查询以匹配属性值和子元素值

Xquery 和查询以匹配属性值和子元素值,xquery,marklogic,cts-search,Xquery,Marklogic,Cts Search,我有包含以下结构的文档: <Reviews> <Review complete="false"> <StartDate>2019-03-05T06:00:00Z</StartDate> <EndDate>2019-03-12T05:00:00Z</EndDate> <Reviewers> <Reviewer userName="

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

<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元素中完成的匹配。有人能提出一种方法吗?

您正在寻找范围查询,如。它允许您为子查询选择联合祖先。下面是一些显示其工作原理的代码:

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
请注意,如果需要未筛选搜索的准确结果,则需要启用位置索引


您正在寻找范围查询,如。它允许您为子查询选择联合祖先。下面是一些显示其工作原理的代码:

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
请注意,如果需要未筛选搜索的准确结果,则需要启用位置索引