Reputation: 21
I have to search a xml based on two attributes and it's element value. For this I have used cts:near-query with distance zero. But am getting xml that doesn't contain the matching value. I have enabled the position values in settings and done reindexing, too. Please find the below XML Mismatched XML one:
<cars>
<car a="subject" b="89">Indian Bank</car>
<car a="subject" b="79">Central Banks</car>
<car a="subject" b="90">Coriando banks</car>
</cars>
I have query like cts:near-query
with two attribute range query with a=subject
and b>=89
and with one element word query central banks
with distance zero. I don't want this XML to be returned while searching. Please help me in resolving this.
Exact rules: The XML which contains a=subject and b>=89 and element value of Central banks should be returned while searching. But with the below query in comment am getting the above document.
cts:and-query((
cts:near-query((
cts:element-attribute-range-query(xs:QName("car"), xs:QName("b), ">=", 89),
cts:element-attribute-range-query(xs:QName("car"), xs:QName("a), "=", "subject"),
cts:element-word-query(xs:qname("car"), "Central Banks")
),0)
))
Upvotes: 0
Views: 89
Reputation: 20414
This would work:
xdmp:document-insert("/cars.xml",
<cars>
<car a="subject" b="89">Indian Bank</car>
<car a="subject" b="79">Central Banks</car>
<car a="subject" b="90">Coriando banks</car>
</cars>)
;
let $car := xs:QName("car")
let $a := xs:QName("a")
let $b := xs:QName("b")
return
cts:search(collection()/cars/car, cts:element-query($car, cts:and-query((
cts:element-attribute-value-query($car, $a, "subject"),
cts:element-attribute-value-query($car, $b, "79"),
cts:word-query("Central Banks")
))))
You can use an element-query to constrain sub-queries to a particular element, usually works better than a near-query (which requires position indexes to be enabled too).
Attribute-value-queries where the element name matches that of the parent element-query will include attributes on the element from the element-query. I didn't have range indexes on attributes a
and b
, but the same applies for attribute-range-queries.
Other element range/value/word queries inside the element-query however, apply to descendants only. So you need to use a word-query to look at the content of element.
The searchable expression pinpointing a specific car will then isolate the exact car that matches the query. Note though that this requires filtering, which usually slows down searching. If you save each car in a separate document, you could do an unfiltered search for better performance. It might also elevate the need for the wrapping element-query.
HTH!
Upvotes: 2