我有以下地图地图:
<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 *'...
的关键字这可以有效地完成吗?
你的时间
雨果
答案 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