簡體   English   中英

使用OR在MarkLogic上進行Xquery

[英]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元素。 我的目標是為每個匹配的文檔返回所有NameCity元素以及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-querycts: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-queryvalue-query及其兄弟時,會有一個隱式OR,並且可以從索引中更有效地解析此查詢,所以盡可能這樣做。

其次,個人可能會匹配多個電話號碼,因此您需要額外的內部循環才能有效地按個人分組。

我不會為此創建一個范圍索引 - 沒有必要,並且它不一定更快。 默認情況下,元素值有索引,因此您可以利用元素值查詢

您可以使用SearchAPI和一點XSLT完成所有這些操作。 這樣可以輕松地在單個查詢中開始組合名稱和數字以及其他條件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM