基于密钥通配符搜索地图

时间:2014-08-21 10:15:08

标签: marklogic

我有以下地图地图:

<map:map xmlns:map="http://marklogic.com/xdmp/map" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<map:entry key="101201">
<map:value>
"content"
</map:value>
</map:entry>
... more maps ...

现在我想使用通配符基于密钥搜索/过滤地图。

实际上我想基于key =“101201”的前4个字符进行过滤,所以key =“1012 **”。

问题:给我所有的地图都有一个匹配'1012 *'...

的关键字

这可以有效地完成吗?

你的时间

雨果

3 个答案:

答案 0 :(得分:1)

内存映射(或节点)没有索引。但是,您可以在数据库中持久保存映射的XML序列化,而不是使用索引解析查询。要保存地图XML:

let $map := map:new(( map:entry("test", "1, 2") ))
return xdmp:document-insert("/map.xml", document { $map })

您可以将cts:element-attribute-value-query与通配符选项一起使用,而无需其他配置:

cts:search(/map:map/map:entry,
  cts:element-attribute-value-query(
    xs:QName("map:entry"), xs:QName("key"), "1012*", ("wildcarded")))

或者,您可以创建元素属性范围索引,并使用cts:element-attribute-value-match

cts:element-attribute-value-match(
  xs:QName("map:entry"), xs:QName("key"), "1012*")

答案 1 :(得分:1)

这可以有效地完成吗?是。不会有任何I / O或网络流量,只有CPU。

map:keys($map)[starts-with(., '1012')]

map:get($map, map:keys($map)[starts-with(., '1012')])

但是,如果这是一个常见的用例,那么您可能需要构建一个地图地图。一个映射将具有四位数密钥,并且每个条目将包含以相同前缀开头的六位数密钥的映射。这样,您可以使用map:get获得四位数匹配,使用substring获得六位数匹配,并使用map:get两次调用。

map:get($m, substring($id, 1, 4))

map:get(map:get($m, substring($id, 1, 4)), $id)

由您来决定优化哪个用例。

答案 2 :(得分:0)

这里没有涉及索引,这限制了你可以做的技巧。这可行,但我不确定它会如何大规模表现:

let $map-of-maps :=
  map:new((
    map:entry('10000', map:new((map:entry('key1', 'value1'), map:entry('key2', 'value2')))),
    map:entry('20000', map:new((map:entry('key3', 'value3'), map:entry('key4', 'value4'))))
  ))
let $keys := 
  for $key in map:keys($map-of-maps) 
  where fn:matches($key, '1000*') 
  return $key
return $keys