[英]Xquery on MarkLogic using OR
這是一個新手MarkLogic問題。 想象一下像這樣的xml結構,這是我真正的業務問題的凝結:
<Person id="1">
<Name>Bob</Name>
<City>Oakland</City>
<Phone>2122931022</Phone>
<Phone>3123032902</Phone>
</Person>
請注意,文檔可以並且將具有多個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)
它正確地執行查詢,但它返回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>
所以我認為我需要某種形式的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>
祝你好運。
這就是我要做的事情:
let $numbers := ("3738494044", "2373839383", "3933849383")
return
<results>{
for $person in cts:search(/Person, cts:element-value-query(xs:QName("Phone"),$numbers))
return
<match id="{data($person/@id)}" name="{data($person/Name)}" city="{data($person/City)}">
{
for $phone in $person/Phone[cts:contains(.,$numbers)]
return element phone {$phone}
}
</match>
}
首先,當將多個值傳遞給word-query和value-query及其兄弟時,會有一個隱式OR,並且可以從索引中更有效地解析此查詢,所以盡可能這樣做。
其次,個人可能會匹配多個電話號碼,因此您需要額外的內部循環才能有效地按個人分組。
我不會為此創建一個范圍索引 - 沒有必要,並且它不一定更快。 默認情況下,元素值有索引,因此您可以利用元素值查詢 。
您可以使用SearchAPI
和一點XSLT
完成所有這些操作。 這樣可以輕松地在單個查詢中開始組合名稱和數字以及其他條件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.