问题
There are 2 collections /test/123 and test/567 I want to return the latest document of both the collections.
let $a := cts:collection-match("/test/*")
for $t in $ a
let $latest :=(
for $doc in fn:collection( $t)
order by $doc//timestamp descending
return $doc)[1]
return fn:concat($latest//id/text(),",",$latest//timestamp/text())
- Is there a better to get the latest document from the collections
I want the final output of query after searching both the collection to be in descending order for timestamp
Output
1234, 2018-04-05T11:28:47.040Z 4567,2018-04-05T11:28:47.722Z
Expected
4567,2018-04-05T11:28:47.722Z
1234, 2018-04-05T11:28:47.040Z
回答1:
I think the answer from @wst in your earlier question talking about just one collection (see https://stackoverflow.com/a/49678200/918496), can be adapted to work for multiple collections as well. It is mostly a matter of placing the parentheses differently. Moreover, fn:collection accepts a sequence too, so adapting the earlier solution would be almost trivial:
let $latest :=(
for $doc in fn:collection(
cts:collection-match("/test/*")
)
order by $doc//timestamp descending
return $doc
)[1]
return fn:concat($latest//id/text(),",",$latest//timestamp/text())
<update>
Re-reading the question (the added Expected section helped, thanks), I see I may have misunderstood the desired output. You are not looking for the most recent result across all matching collections, but you want the most recent of each collection, shown in descending order. That looks slightly different, and you weren't very far off at all. You just need a second order by clause:
let $a := cts:collection-match("/test/*")
for $t in $a
let $latest := (
for $doc in fn:collection($t)
order by $doc//timestamp descending
return $doc
)[1]
order by $latest//timestamp descending
return fn:concat($latest//id/text(),",",$latest//timestamp/text())
Having said that, there might be more performant ways of doing this with MarkLogic. If you have a dateTime range index on your timestamp, you could allow MarkLogic to make use of that to find the first in ascending or descending order real quickly. The clearest way of doing that is using cts:search with a cts:index-order argument. Something like:
let $a := cts:collection-match("/test/*")
for $t in $a
let $latest := cts:search(
collection(),
cts:collection-query($t),
cts:index-order(
cts:element-reference(
fn:QName("","timestamp"),
"type=dateTime"
),
"descending"
)
)[1]
order by $latest//timestamp descending
return fn:concat($latest//id/text(),",",$latest//timestamp/text())
</update>
HTH!
来源:https://stackoverflow.com/questions/49678817/search-latest-document-from-multiple-collection