[xquery-talk] search mechanism

Martin Probst martin at x-hive.com
Thu Apr 6 18:26:52 PDT 2006

Hi Peter,

> Here is my query attempt which results in the following exception: 
> "unexpected token: ) [at line 11, column 9]"
> let $res :=
> 	let $ids := distinct-values(
> 		let $ids1 := 
> 			for $id1 in //text//abstract &= 'peter'
> 			return xs:string($id1/ancestor::text/@id)
> 		let $ids2 := 
> 			for $id2 in //text//title &= 'java'
> 			return xs:string($id2/ancestor::text/@id)
> 		where $ids1 = $ids2
>     	return
> 	)
> 	for $doc in //text[@id = $ids]
>    	order by year-from-date($doc//date)
>    	return $doc
> return subsequence($res, 10, 20)

What is that &= syntax you're using? I've never seen that.

You always need an expression following the "return" keyword, normally a 
variable from the preceding FLWOR expression. In this case however, you 
need to do that a little different. let binds the whole sequence to a 
variable and '=' is an existential comparison, e.g. 'one of the left 
side equals one of the right side'. This means take all IDs from the 
first query ('peter') and take all IDs from the second query ('java'). 
Then if one of the IDs matches one of the other IDs, return all.

I'd guess that what you want to say is different, e.g. put this into the 
distinct-values() block.

  	for $id1doc in //text//abstract[contains(.,'Peter')]
	let $id1 := $id1doc/ancestor::text[1]/@id/string()
	for $id2doc in //text//title[contains(.,'java')]
	let $id2 := $id2doc/ancestor::text[1]/@id/string()
	where $id1 = $id2
	return $id1

I.e. for each document that contains Peter in the abstract and each 
document that contains Java in the title, if the IDs are equal return 
one of them. While this looks like a nested join smart XQuery processors 
can rewrite it to a hash-merge and for not so smart processors you can 
rewrite it.


More information about the talk mailing list