如何在marklogic中获取2个集合之间的差异URI

How to get the difference URI between 2 collection in marklogic

我有两个合集。

我需要根据文件名获取两个集合之间的差异uri。

示例场景:

Collection 1:

/data/1.xml
/data/2.xml
/data/3.xml


collection 2:

/test/1.xml
/test/2.xml
/test/3.xml
/test/4.xml
/test/5.xml

output:
/data/1.xml
/data/2.xml
/data/3.xml
/test/4.xml
/test/5.xml

设置符号:

增量:(收益率 'a')

let $c1 := ('a', 'b', 'c')
let $c2 := ('b', 'c', 'd')

return $c1[fn:not(.= $c2)]

路口:(产生 b、c)

let $c1 := ('a', 'b', 'c')
let $c2 := ('b', 'c', 'd')

return $c1[.= $c2]

对其他两个排列反转 c1 和 c2。

为了更好地阅读,请查看来自 Dave Cassel

post

按照 David 的建议使用 set delta 是正确的,但您需要首先为 URI 生成文件名键。地图对此非常有帮助,它可以很容易地保持文件名键与其原始 URI 相关联。

首先生成两个具有文件名键和 URI 值的映射。然后,在映射键上使用 set delta,生成一系列 diff 文件名。然后从其源映射中获取这些文件名的 URI:

let $x := (
  "/data/1.xml",
  "/data/2.xml",
  "/data/3.xml")
let $y := (
  "/test/1.xml",
  "/test/2.xml",
  "/test/3.xml",
  "/test/4.xml",
  "/test/5.xml")
let $map-x := map:new($x ! map:entry(tokenize(., '/')[last()], .))
let $map-y := map:new($y ! map:entry(tokenize(., '/')[last()], .))
let $keys-diff-y := map:keys($map-y)[not(. = map:keys($map-x))]
let $diff-y := map:get($map-y, $keys-diff-y)
return ($x, $diff-y)

两种替代解决方案:

第一种方法,使用一致的键(最后一个斜线后的子字符串)将每个项目放入映射中,然后 select 每个键的映射中的第一个项目:

let $x := (
  "/data/1.xml",
  "/data/2.xml",
  "/data/3.xml")
let $y := (
  "/test/1.xml",
  "/test/2.xml",
  "/test/3.xml",
  "/test/4.xml",
  "/test/5.xml")
let $intersection := map:map()
let $_ := ($x, $y) ! ( 
  let $key := tokenize(., "/")[last()] 
  return 
    map:put($intersection, $key, (map:get($intersection, $key), .))
)
return 
  for $key in map:keys($intersection)
  for $uri in map:get($intersection, $key)[1]
  order by number(replace($uri, ".*/(\d+).xml", ''))
  return $uri

第二种方法,确保只为给定键设置第一项:

let $x := (
  "/data/1.xml",
  "/data/2.xml",
  "/data/3.xml")
let $y := (
  "/test/1.xml",
  "/test/2.xml",
  "/test/3.xml",
  "/test/4.xml",
  "/test/5.xml")

let $intersection := map:map()
let $_ := ($x, $y) ! ( 
  let $key := tokenize(., "/")[last()] 
  return 
    if (fn:exists(map:get($intersection, $key))) then ()
    else map:put($intersection, $key, .)
)
return 
  for $uri in map:get($intersection, map:keys($intersection))
  order by number(replace($uri, ".*/(\d+).xml", ''))
  return $uri

order by 是可选的,但对于地图,您可能没有一致的键顺序。根据您的需要进行自定义(即首先是 /data/ uris,然后是 /test/ uris 等),或者如果您不关心 URI 的顺序,则将其删除。