1

Providing I have such an element in ML:

 <top-level-cote-mgt-rights>
    <token>SUPPORT</token>
    <token role="ADMIN">A/B/C</token>
    <token role="APPROVER">A/B/C</token>
    <token role="ADMIN">X/Y/Z</token>
    <token role="APPROVER">X/Y/Z</token>
    <token role="ADMIN">ADMIN/ONLY</token>
  </top-level-cote-mgt-rights>

The following query is meant to look for token elements for which both the value is "ADMIN/ONLY" and the role attribute is "APPROVER"

let $uris := cts:uris('', (), cts:and-query((
  cts:collection-query('/test/data'),
  cts:element-query(xs:QName('top-level-cote-mgt-rights'), 
    cts:element-query(xs:QName('token'),
      cts:and-query((
        cts:element-attribute-word-query(xs:QName('token'), xs:QName('role'), 'APPROVER', ('exact'))
        ,cts:word-query('ADMIN/ONLY', ('exact'))
      ))
    )
  )
)))
return fn:doc($uris)//one:top-level-cote-mgt-rights

It should not return any result, and yet, it does return

<top-level-cote-mgt-rights xmlns="http://one.oecd.org/one">
   <token>SUPPORT</token>
   <token role="ADMIN">A/B/C</token>
   <token role="APPROVER">A/B/C</token>
   <token role="ADMIN">X/Y/Z</token>
   <token role="APPROVER">X/Y/Z</token>
   <token role="ADMIN">ADMIN/ONLY</token>
</top-level-cote-mgt-rights>

Looks like it is matching separately on an "token" value and on an "token" attribute, but not from the same "token" like I am trying to achieve.

What am I doing wrong?

1 Answers1

1

You would expect false positives using cts:element-query in this circumstance: cts:element-query actually scopes the matching element in which the enclosing query will look up. My understanding is that cts runs in the relevance/scoring fashion.

You can use query trace to try/test how true | false a composable query is ( if your query is a straight cts:element-attribute-value-query , you shouldn’t expect the false positive ).

I suggest two solutions:

Use native XPath to eliminate the false positive.

Should you wish have the MarkLogic way, try this technique:

cts:search(
  fn:collection("/test/data")//one:top-level-cote-mgt-rights,
  cts:near-query(
    ( cts:element-attribute-value-query(xs:QName("one:token"), xs:QName("role"), "APPROVER", "exact"),
      cts:element-value-query(xs:QName("one:token"), "ADMIN/ONLY", "exact")
    ),
    0
  )
)
  • If case is of no concern, remove "exact".
  • You can benchmark the query performance with the word positions index.
Fiona Chen
  • 1,358
  • 5
  • 16
  • Might also need element value positions and attribute value positions? Not sure xpath would be better, doesn't it always require filtering? You can check the plans of everything to see what is being used. That near-query looks like the answer to me. – asusu Nov 22 '22 at 20:22