If the order by happened before the return, then wouldn't all the $start
values be close, and all the return times be close?

That is, no return time should occur before any start time.

I tried a variation:

for $i at $x in 1 to 5
let $_ := xdmp:sleep(1)
let $start := xdmp:elapsed-time()
let $o := xdmp:random()
order by $o descending
return text { $x, $start, xdmp:elapsed-time(), xdmp:log ('i: '||$i) }

While I get random ordering in the returns like

2 PT0.002364S PT0.002377S
4 PT0.004754S PT0.004772S
3 PT0.003549S PT0.003567S
1 PT0.001153S PT0.001188S
5 PT0.005944S PT0.005954S

I always see something like

2014-10-09 09:24:08.735 Info: App-Services: i: 1
2014-10-09 09:24:08.736 Info: App-Services: i: 2
2014-10-09 09:24:08.737 Info: App-Services: i: 3
2014-10-09 09:24:08.738 Info: App-Services: i: 4
2014-10-09 09:24:08.739 Info: App-Services: i: 5

in the log.  So it seems the return evaluation order does not depend on the
ordering.


On Thu, Oct 9, 2014 at 5:54 AM, Rachel Wilson <rachel.wil...@bbc.co.uk>
wrote:

> I keep looking at this test, and while I understand the results given your
> conclusion, I'm not sure I understand how it would look differently if the
> order by happened before the return?
>
> I like how the test doesn't depend on any natural document order so I'd
> like to understand it - I think it'll be handy to be able to write tests
> like this myself in future.
>
> -----Original Message-----
> From: Michael Blakeley <m...@blakeley.com>
> Reply-To: MarkLogic Developer Discussion <general@developer.marklogic.com>
> Date: Thursday, 2 October 2014 20:41
> To: MarkLogic Developer Discussion <general@developer.marklogic.com>
> Subject: Re: [MarkLogic Dev General] order by clause ignored?
>
> I try not to rely on evaluation order anywhere, if I can help it. But I'm
> not sure whether MarkLogic's behavior matches the spec or not.
>
> According to http://www.w3.org/TR/xquery/#id-orderby-return "the resulting
> order determines the order in which the return clause is evaluated".
>
> I like tests, so here's one:
>
> for $i at $x in 1 to 5
> let $_ := xdmp:sleep(1)
> let $start := xdmp:elapsed-time()
> order by $x descending
> return text { $x, $start, xdmp:elapsed-time() }
> =>
> 5 PT0.006194S PT0.006221S
> 4 PT0.004826S PT0.004854S
> 3 PT0.003606S PT0.00364S
> 2 PT0.002314S PT0.002325S
> 1 PT0.001134S PT0.001211S
>
> With 7.0-4, the smallest elapsed-time values are at the end and both
> elapsed-time values match closely. To me this suggests that the return
> clause was evaluated before the results were sorted, not after.
>
> -- Mike
>
> On 2 Oct 2014, at 11:19 , Rachel Wilson <rachel.wil...@bbc.co.uk> wrote:
>
> > 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
> >
>
> _______________________________________________
> 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

Reply via email to