这是一个新手MarkLogic问题.想象一下像这样的xml结构,这是我真正的业务问题的凝结:
<Person id="1">
<Name>Bob</Name>
<City>Oakland</City>
<Phone>2122931022</Phone>
<Phone>3123032902</Phone>
</Person>
Run Code Online (Sandbox Code Playgroud)
请注意,文档可以并且将具有多个Phone元素.
我要求从每个文档中返回信息,该文档的Phone元素与电话号码列表中的任何一个匹配.该列表中可能包含几十个电话号码.
我试过这个:
let $a := cts:word-query("3738494044")
let $b := cts:word-query("2373839383")
let $c := cts:word-query("3933849383")
let $or := cts:or-query( ($a, $b, $c) )
return cts:search(/Person/Phone, $or)
Run Code Online (Sandbox Code Playgroud)
它正确地执行查询,但它返回Results元素内的一系列Phone元素.我的目标是为每个匹配的文档返回所有Name和City元素以及Person元素的id属性.例:
<results>
<match id="18" phone="2123339494" name="bob" city="oakland"/>
<match id="22" phone="3940594844" name="mary" city="denver"/>
etc...
</results>
Run Code Online (Sandbox Code Playgroud)
所以我认为我需要某种形式cts:search允许这个布尔功能,但也允许我指定返回每个文档的哪个部分.那时我可以进一步处理结果XPATH.我需要有效地执行此操作,例如,我认为返回文档uri的列表然后在循环中查询每个文档是不高效的.谢谢!
你的方法没有你想象的那么糟糕.只需进行一些更改即可使其按您的喜好工作.
首先,你最好使用cts:element-value-query而不是cts:word-query.它允许您将搜索到的值限制为特定元素.当您为该元素添加元素范围索引时,它表现最佳,但不是必需的.它也可以依赖于始终存在的单词索引.
其次,没有必要cts:or-query.两者cts:word-query和cts:element-value-query函数(以及所有其他相关函数)都接受多个搜索字符串作为一个序列参数.它们被自动视为or-query.
第三,电话号码是你的" 主键,在结果",所以返回所有匹配的手机元素的列表是要走的路.您只需要意识到生成的Phone元素仍然知道它们来自何处.您可以轻松地使用XPath导航到父级和兄弟级别.
第四,没有什么可以阻止搜索结果的循环.这可能听起来有点奇怪,但它不会花费太多额外的性能.实际上,在MarkLogic Server中它几乎可以忽略不计.当您尝试返回许多结果(超过几千个)时,大多数性能可能会丢失,在这种情况下,大部分时间都会在序列化时丢失.如果您可能需要处理大量搜索结果,那么立即开始使用分页是明智之举.
要获得您的要求,您可以使用以下代码:
<results>{
for $phone in
cts:search(
doc()/Person/Phone,
cts:element-value-query(
xs:QName("Phone"),
("3738494044", "2373839383", "3933849383")
)
)
return
<match id="{data($phone/../@id)}" phone="{data($phone)}" name="{data($phone/../Name)}" city="{data($phone/../City)}"/>
}</results>
Run Code Online (Sandbox Code Playgroud)
祝你好运.
| 归档时间: |
|
| 查看次数: |
1062 次 |
| 最近记录: |