Problem with XQuery using <=, >= comparison on collect

Hello Everyone,

I would like to ask for some help to see if my XQuery is wrong or why I am not getting the output that I expect. Ok, so first a little background on the problem. I have a schema of an XML object described below descriptively:

<NC> 
    <F> 
          <PROT>XXXXXXXX</PROT> 
    </F> 
 
    <TF> 
          <DATESTRING>20090103</DATESTRING> 
    </TF> 
     
    ..... 
 
    <TF> 
          <DATESTRING>20090110</DATESTRING> 
    </TF>      
 
</NC>

The XML object NC consists of having multiple inner elements named TF each with an element string called DATESTRING, which has a standard Tamino Index applied to it. The DATESTRING stores a date using a standard format of YYYYMMDD, this lets us do string comparisons on dates easily.

So, my problem is that I want to have a XQuery query that lets me apply multiple date ranges to filter the data. So far I have come up with this:

for $q in input()/NC sort by (./F/PROT) 
	where 
	($q/TF/DATESTRING >= '20090101')  and 
	($q/TF/DATESTRING <= '20090105')  and 
	($q/TF/DATESTRING >= '20090106')  and 
	($q/TF/DATESTRING <= '20090109')   
return <RESULT><INO>{tf:getInoId($q)}</INO> {$q}</RESULT>

So, for example, the above XQuery should return all NC XML objects that have a minimum of two dates (we have two mutually exclusive date ranges) that all fall between January 1-5 and 6-9 in the year 2009. However, currently Tamino gives me objects that satisfy only one of the conditions. For example, for the above XQuery Tamino has returned this object to me, which has two dates of January 10, 2009 that don’t fall in any of the above date ranges.

<NC> 
    <F><PROT>XXXXXXXX</PROT></F> 
    <TF><DATESTRING>20090103</DATESTRING></TF> 
    <TF><DATESTRING>20090110</DATESTRING></TF> 
    <TF><DATESTRING>20090110</DATESTRING></TF>      
</NC>

I guess I don’t understand how Tamino does comparisons across collections inside an XML Object. Can anybody point me in the right direction? Thanks

-Lorenzo

Hi Lorenzo,

The result is correct, maybe you are trapped by the set semantics of XQuery comparisons.

Your condition


   ($q/TF/DATESTRING >= '20090101')  and
   ($q/TF/DATESTRING <= '20090105')  and
   ($q/TF/DATESTRING >= '20090106')  and
   ($q/TF/DATESTRING <= '20090109') 

means:
there is one $q/TF/DATESTRING greater than 20090101 (yes, holds for all three in your result object)
AND
there is one $q/TF/DATESTRING less than 20090105 (yes, holds for 20090103)
AND
there is one $q/TF/DATESTRING greater than 20090106 (yes, holds for 20090110)
AND
there is one $q/TF/DATESTRING less than 20090109 (yes, holds for 20090103)

So all four conditions are met, and the object qualifies

To achieve what you are striving for (select objects that have at least one $q/TF/DATESTRING in the range [20090101,20090105] and at least one in the range [20090106,20090109] you have to ask your query differently, I will post the query here.

The following query achieves what you are looking for:


for $q in input()/NC sort by (./F/PROT)
   where
   $q/TF/DATESTRING[. >= '20090101'  and. <= '20090105']  and
   $q/TF/DATESTRING[. >= '20090106'  and . <= '20090109']  
return <RESULT><INO>{tf:getInoId($q)}</INO> {$q}</RESULT>

best regards

Harald

Thank you, that works perfectly, I was a little unsure of the exact XQuery syntax to use for that case. Thanks again.