如何在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 的顺序,则将其删除。
我有两个合集。
我需要根据文件名获取两个集合之间的差异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 的顺序,则将其删除。