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

时间:2017-12-13 15:41:20

标签: xquery marklogic

我有两个系列。

我需要根据文件名在两个集合之间获得差异。

示例场景:

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

3 个答案:

答案 0 :(得分:4)

使用set delta作为David建议是正确的,但您需要首先为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)

答案 1 :(得分:3)

两种替代解决方案:

首先,使用一致的键(最后一个斜线后面的子串)将每个项目放在地图中,然后在地图中为每个键选择第一个项目:

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", '$1'))
  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", '$1'))
  return $uri

order by是可选的,但是对于地图,您可能没有一致的密钥排序。根据需要自定义(例如/ data / uris,然后/ test / uris等),如果不关心URI的顺序,则删除。

答案 2 :(得分:1)

设置符号:

达美:(收益'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