1

Let's assume I have inserted the below xml in the DB.

<root>
    <name>Dixit</name>
    <entry>
        <vol>1212</vol>
        <title>title1</title>
        <isbn>
            <value>123456</value>
        </isbn>
    </entry>
    <entry>
        <vol>1212</vol>
        <title>title1</title>
    </entry>
</root>

How can I write a cts query which will return me the <entry> nodes with <vol> as 1212 & <title> as title1 & should not have <isbn> element.

For the above xml the output should be.

<entry>
    <vol>1212</vol>
    <title>title1</title>
</entry>
Dixit Singla
  • 2,540
  • 3
  • 24
  • 39

2 Answers2

3

One would normally use cts:not-query(cts:element-query(xs:QName("isbn"), cts:true-query())) to find cases in which the isbn element is missing, but unfortunately the cts:not-query causes the query to look at the entire document, and since your XML document has multiple entries, ones with isbn, and ones without, that will not give the result you hope to see.

You will either need to post-filter the result from cts:search manually using XPath, for instance like:

cts:search(
  //entry,
  cts:and-query((
    cts:element-query(xs:QName("vol"), "1212"), 
    cts:element-query(xs:QName("title"), "title1")
  ))
)[empty(isbn)]

Or split your document to save each entry as a separate document. Then the cts:not-query would work, and give a more convenient solution that scales well too.

HTH!

grtjn
  • 20,254
  • 1
  • 24
  • 35
  • Thanks, currently I am doing it with XPath. One more question on this. If the cts:search is returning more than a million documents, using xpath will be slow? – Dixit Singla Apr 07 '17 at 02:37
  • XPath itself is not really slow, but imagine the database needing to pull up a million results, and execute that XPath on them one by one to find the right ones, that will indeed be slow. Hence my suggestion to save entries as separate docs, that will give much better options.. – grtjn Apr 07 '17 at 04:43
0

try like, but you will get isbn as well,

cts:search(//entry,     
cts:and-query((cts:element-query(xs:QName("vol"), "1212"), 
cts:element-query(xs:QName("title"), "title1"))))

to completely avoid isbn, fire two cts searches as,

<entry> 
{
(cts:search(//vol, cts:element-query(xs:QName("vol"), "1212")),    
cts:search(//title, cts:element-query(xs:QName("title"), "title1")))
}
</entry>
Ashok Waghmare
  • 188
  • 3
  • 6