#xquery #marklogic
#xquery #marklogic
Вопрос:
<MasterData>
<Name>AA</Name>
<EmpId>123</EmpId>
<AccountNo>111</AccountNo>
<IFSC>ABC</IFSC>
<AccountData>
<AccountNo>111</AccountNo>
<IFSC>ABC</IFSC>
</AccountData>
<AccountData>
<AccountNo>222</AccountNo>
<IFSC>DEF</IFSC>
</AccountData>
</MasterData>
У меня в базе данных есть такой XML, у меня есть требование проверить комбинацию AccountNo IFSC, присутствующую в MasterData (не в разделе AccountData), и сравнить со всеми документами, присутствующими в коллекции, и проверить, соответствует ли она данным, представленным в разделе AccountData, если их соответствие идентифицируетURI документа.
Сначала определите уникальную комбинацию AccountNo IFSC из раздела Masterdata, а затем проверьте, присутствует ли эта комбинация в каком-либо разделе AccountData, в этом xml есть другие элементы, кроме AccountNo и IFSC
Ответ №1:
Если у вас были индексы диапазона AccountNo
IFSC
для элементов и, то вы могли бы:
- извлеките набор значений из
AccountNo
,IFSC
, иcts:uri-reference()
сcts:value-tuples()
помощью . - создайте карту, используя составной ключ со значениями
AccountNo
иIFSC
и URI в качестве значений для этих записей карты - удалите любую запись, с которой связан только один URI
- возвращает карту, которая будет иметь набор URI, соответствующий каждой комбинации значений
AccountNo
иIFSC
Что-то вроде этого:
let $accountNumber-IFSC :=
cts:value-tuples(
(
cts:element-reference(xs:QName("AccountNo")),
cts:element-reference(xs:QName("IFSC")),
cts:uri-reference()
)
)
let $map := map:new()
let $_create_map_value_to_uris := for $co-occurrence in $accountNumber-IFSC
let $key := concat($co-occurrence[1], " ", $co-occurrence[2])
let $value := (map:get($map, $key), $co-occurrence[3])
return map:put($map, $key, $value)
let $_prune_single_uri :=
for $key in map:keys($map)
let $value := map:get($map, $key)
where not(tail($value))
return
map:put($map, $key, ())
return
$map
Если вам просто нужен список URI, вы можете инвертировать map: -$map
и вернуть его ключи: return map:keys(-$map)
Если бы у вас был индекс диапазона EmpId
, вы могли бы использовать его вместо URI документа.
Ответ №2:
Используя функции API Optic, вы можете сделать нечто подобное с индексами диапазона элементов:
import module namespace op = "http://marklogic.com/optic" at "/MarkLogic/optic.xqy";
op:from-lexicons(
map:entry("AccountNo", cts:element-reference(xs:QName("AccountNo")))
=> map:with("IFSC", cts:element-reference(xs:QName("IFSC")))
=> map:with("URI", cts:uri-reference())
)
=> op:group-by(
("IFSC", "AccountNo"),
(
op:group-concat("URIs", "URI", map:entry("separator", ", ")),
op:count("count", op:col("URI"))
)
)
=> op:where(op:gt(op:col("count"), 1))
=> op:result()