search latest document from multiple collection

你说的曾经没有我的故事 提交于 2019-12-24 21:46:15

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!