Thanks Mike, Are you saying never to do anything in the return statement that depends on the order - that the order by clause only orders the final results. It's so surprising because it does *mostly* work, until I added the order by clause it was *completely* wrong. And it's worked fine for other simple data sets - just not against production data sadly :-)
I think I've been lead astray in my expectations by the order by examples for the return statement section in this article http://www.stylusstudio.com/xquery_flwor.html Oh and a quick check - I'm assuming this is the same for any xquery provider, it's not just a quirk of marklogic optimisation. Thanks for the lessons! Rachel -----Original Message----- From: Michael Blakeley <m...@blakeley.com> Reply-To: MarkLogic Developer Discussion <general@developer.marklogic.com> Date: Thursday, 2 October 2014 17:42 To: MarkLogic Developer Discussion <general@developer.marklogic.com> Subject: Re: [MarkLogic Dev General] order by clause ignored? The order of operations in a FLWOR isn't guaranteed. The return expression could be evaluated before the sorting is done. You might also be interested to know that maps are unordered. So you can put those items into the map in any order you like, but the keys will end up in whatever internal order the map uses. That should be consistent, but won't be under your control. As an alternative you can order the keys when processing the map. Or consider using json:object instead. That's like a map but has an ordered sequence of keys. -- Mike On 2 Oct 2014, at 09:17 , Rachel Wilson <rachel.wil...@bbc.co.uk> wrote: > I realise this is more of an xquery question but everyone here is >stumped :-s > > I have a query that is trying to calculate some earliest and latest >dates that an event occurred. The events are represented in xml like >this: > > <publication> > <publicationDateTime>2013-08-14T15:06:51.921302Z</publicationDateTime> > <documents> > <document> > <id>b119c2a3-5436-59d2-9771-a67f8e2b4172</id> > <version>1</version> > </document> > </documents> > </publication> > > There are two events for the this particular document (i.e. with the >same document id), and therefore two publication documents on different >days. In order to work out the first and last dates I'm sorting all my >publication docs by publication date, then taking the sorted publication >documents in order I'm iterating through the publication document ids in >order and remembering them in the correct maps for earliest seen and >latest seen dates. However the results in the map are as if the >publication documents are coming out in document order. > > If I run this query the document dates are coming out in the right order >as I'd expect: > ------------------------------------------------------------------ > let $earliestPubDates := map:map() > let $latestPubDates := map:map() > let $buildMaps := > for $x in doc()/publication > let $publishedDate := $x/publicationDateTime/string() > let $documents := $x/documents/document > order by $x/publicationDateTime > return > (: map building stuff commented out in order to see how the dates >are being ordered :) > $publishedDate > > return $buildMaps > --------------------------------------------------------------------- > returns: > 2013-08-14T15:06:51.921302Z > 2014-09-03T14:46:07.757612Z > > > > However, after someone showed me how to debug the loop a little with an >error statement, I'm finding that the first publication processed is the >later one, not the earlier one. It looks like the order by in this case >is being ignored. Could someone tell me how and why? > > > > >-------------------------------------------------------------------------- >-- > let $earliestPubDates := map:map() > let $latestPubDates := map:map() > > let $buildMaps := > for $x in doc()/publication > let $documents := $x/documents/document > order by $x/publicationDateTime > return > for $contentId in $documents/id/string() > let $publishedDate := $x/publicationDateTime/string() > let $putEarliest := if (not(map:contains($earliestPubDates, >$contentId))) then ( > let $dummy := map:put($earliestPubDates, >$contentId, $x/publicationDateTime) > let $a := error("Adding earliest published >date " || $x/publicationDateTime) > return $dummy > ) else () > let $putLatest := map:put($latestPubDates, $contentId, >$publishedDate) > return () > > return $buildMaps > ---------------------------------- > Returns (in an error stack trace): "Adding earliest published date >2014-09-03T14:46:07.757612Z" > > > Is it something to do with when the order by is applied to the statement? > > Any help gratefully received > Rachel > _______________________________________________ > General mailing list > General@developer.marklogic.com > http://developer.marklogic.com/mailman/listinfo/general _______________________________________________ General mailing list General@developer.marklogic.com http://developer.marklogic.com/mailman/listinfo/general _______________________________________________ General mailing list General@developer.marklogic.com http://developer.marklogic.com/mailman/listinfo/general