0

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-attribut‌​e-range-query(xs:QNa‌​me("car"), xs:QName("‌​b), ">=", 89),
    cts:elem‌​ent-attribute-range-‌​query(xs:QName("car"‌), xs:QName("a), "=", "‌subject"),
    cts:elemen‌​t-word-query(xs:qnam‌​e("car"), "Central Banks")
  ),0)
))
Dave Cassel
  • 8,352
  • 20
  • 38
UHM
  • 21
  • 1
  • Please have a look at the [FAQ] for formatting options and look at the preview before posting -- your XML input was not formatted as code and thus not displayed (but the browser tried to render it). I'm still not sure what you want to achieve, though -- what are the exact rules for filtering, what is the expected output? If you already tried some query, also post that code and the error message/wrong output. – Jens Erat Jul 08 '17 at 09:49
  • @JensErat please find the query below cts:and-query((cts:near-quernear-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)))) – UHM Jul 08 '17 at 10:06
  • Never post longer code snippets in comments, always edit them into your question (and apply some formatting including reasonable indentation and linewraps, don't expect people to be happy digging through thee lines of code and trying to get an understanding how they're parenthesized). Anyway: There is no element matching all three requirements you posted? – Jens Erat Jul 08 '17 at 10:47
  • Ya that's my problem actually the above XML is returning for the query. Am sorry for not intending the queries since am out of station I couldn't able to connect my lap so please apologize me – UHM Jul 08 '17 at 12:06

1 Answers1

2

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!

grtjn
  • 20,254
  • 1
  • 24
  • 35
  • Thank you for your answer. But I need a query that should satisfy the following conditions : b should be greater than or equal to 89 and a equal to subject with element values as Central Banks. Thanks in advance – UHM Jul 09 '17 at 03:11
  • Matched one: Indian Bank Central Banks Coriando banks – UHM Jul 09 '17 at 07:07
  • 1
    Did you try with the range query instead of the value query, like I suggested? I didn't have range indexes setup, so couldn't test myself.. – grtjn Jul 10 '17 at 04:38
  • If you see my query it doesn't have any value query. For attributes I used attribute range and for values I used element word. So when I use like this it's not searching in same element. Instead it's searching in other elements too. I need a query with near query which is actual requirement. I have enabled position values of each and every thing in DB too. – UHM Jul 10 '17 at 17:15
  • 1
    Please review the answer carefully. I'm using an `element-query` to make sure sub-queries are bound to the same element. – grtjn Jul 10 '17 at 17:56
  • But element-query is looking for all the elements of "car". So it will look in all the three elements instead of single element. If am not wrong if you give 89 as attribute value in your query also it will return the above document. I will check with this and let you know. Thank you so much for your answers – UHM Jul 11 '17 at 04:09
  • 1
    [`cts:element-query`](http://docs.marklogic.com/cts:element-query): `a cts:query matching elements by name with the content constrained by the given cts:query in the second parameter. Searches for matches in the specified element and all of its descendants. If the specified query in the second parameter has any cts:element-attribute-*-query constructors, it will search attributes directly on the specified element and attributes on any descendant elements` – grtjn Jul 11 '17 at 04:37