Reputation: 181
I'm starting with MarkLogic, and I would like to know how can I get documents json from Marklogic with xquery. I've got the next xquery:
xquery version "1.0-ml";
(: Parameter of Input :)
declare variable $ruc as xs:string external;
declare variable $startDate as xs:string external;
declare variable $endDate as xs:string external;
declare function local:findDocumentsByColletion($ruc as xs:string) {
for $i in cts:search(fn:doc(),
cts:and-query((cts:collection-query("TRANSACTION"),
cts:collection-query($ruc))))
return $i
};
for $doc in local:findDocumentsByColletion ($ruc)
return $doc
There is only get documents by collections but I don't know how search by dates with startDate and endDate as parameters for search documents.
I've tried with this example https://docs.marklogic.com/guide/search-dev/rangequery, but it's different because search is just on one document xml.
My function for search by date would be so:
declare function local:findDocumentsByDate($startDate as xs:string, $endDate as xs:string) {
for $doc in local:findDocumentsByColletion ($ruc)
cts:search($doc/Authorization,
cts:element-range-query(xs:QName("Timestamp"), ">=", xs:date($startDate)),
cts:element-range-query(xs:QName("Timestamp"), "<=", xs:date($endDate)))
return $doc
}
But it doesn't work:
[1.0-ml] XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected QName_
Stack Trace
At line 18 column 4:
In xdmp:eval(" xquery version "1.0-ml"; (: Parameter of Inpu...", (), <options xmlns="xdmp:eval"><database>4000066727531963679</database>...</options>)
16. declare function local:findDocumentsByDate($startDate as xs:string, $endDate as xs:string) {
17. for $doc in local:findDocumentsByColletion ($ruc)
18. cts:search($doc/Authorization,
19. cts:element-range-query(xs:QName("Timestamp"), ">=", xs:date($startDate)),
20. cts:element-range-query(xs:QName("Timestamp"), "<=", xs:date($endDate)))
Any suggestions?
Upvotes: 1
Views: 1137
Reputation: 20414
I like the idea of creating reusable functions that can be composed to find the result you are searching for. However, you cannot wrap searches in the way you do, nor would that be performant.
I'd recommend creating functions that provide portions of the total query, instead of doing multiple searches. You compose those into a large query, and execute that with just one cts:search. Something like:
declare function local:findDocumentsByColletion($ruc as xs:string) {
cts:and-query((
cts:collection-query("TRANSACTION"),
cts:collection-query($ruc)
))
};
declare function local:findDocumentsByDate($startDate as xs:string, $endDate as xs:string) {
cts:and-query((
cts:element-range-query(xs:QName("Timestamp"), ">=", xs:date($startDate)),
cts:element-range-query(xs:QName("Timestamp"), "<=", xs:date($endDate))
))
};
cts:search(collection()/Authorization, cts:and-query((
local:findDocumentsByCollection($ruc),
local:findDocumentsByDate($startDate, $endDate)
)))
HTH!
Upvotes: 0
Reputation: 4912
You are almost there. Since you want both range conditions to hold, you need to wrap them in a cts:and-query:
cts:search($doc/Authorization,
cts:and-query((
cts:element-range-query(xs:QName("Timestamp"), ">=", xs:date($startDate)),
cts:element-range-query(xs:QName("Timestamp"), "<=", xs:date($endDate))
))
)
Upvotes: 3