I am trying to query a database of documents in MarkLogic to find any that fit several parameters:
This MUST be true
And EITHER of these must be true:
extra-documents
must have a date-added
field on any of them that is more recent than the provided datenewer-document-date
field that is more recent than the provided dateFor example, someone may pass in an authorId
of 10
, and a dateTime
of 2017-01-01T00:00:00
Below are samples explaining why they should/shouldn't be returned (removed extraneous XML)
This document should be returned because it has an extra-document with a date-added that is more recent than the provided date, and a matching author.
<metadata>
<extra-documents>
<extra-document>
<date-added>2018-09-11T00:00:00</date-added>
</extra-document>
</extra-documents>
<book-authors>
<book-author>10</book-author>
<book-author>20</book-author>
</book-family-authors>
</metadata>
This document should be returned because it has a newer-document-date greater than the provided date
<metadata>
<extra-documents>
<extra-document>
<date-added>2000-09-11T00:00:00</date-added>
</extra-document>
</extra-documents>
<book-authors>
<book-author>10</book-author>
<book-author>20</book-author>
</book-family-authors>
<newer-document-date>2019-02-03T00:00:00</newer-document-date>
</metadata>
This document should NOT be returned because it is missing the author, even though it fills the date requirement on both the extra-document and the newer-document-date
<metadata>
<extra-documents>
<extra-document>
<date-added>2020-09-05T00:00:00</date-added>
</extra-document>
</extra-documents>
<book-authors>
<book-author>20</book-author>
</book-family-authors>
<newer-document-date>2019-02-03T00:00:00</newer-document-date>
</metadata>
I am new to using cts:search
, and am having trouble figuring out how to build a complex query like this that can search specific nodes. The best I have come up with is this:
cts:search(/*,
cts:and-query ((
cts:search(/*:metadata/*:book-authors/*:book-author, $author-id),
cts:element-query(
fn:QName("http://example.com/collection/book-metadata", "newer-document-date"),
cts:true-query()
), <-- this element-query was an attempt to make sure the field exists on the book, as some books don't have this field
cts:search(/*:metadata,
cts:element-range-query(fn:QName("http://example.com/collection/book-metadata", "newer-document-date"), "<", $date-from)
))
)
)
However, this doesn't seem to work correctly, and trying to add the 3rd requirement has been extremely difficult, to the point that I am simply trying to get these first 2 implemented right now. Any help on this is appreciated. I'm unsure if cts:search
is the best approach for this, or if I am using things like /*:metadata...
correctly for searching specific fields
Wrap the two queries looking for either the existence of the date-added
element or the newer-document-date
with a value less than the $date-from
inside of a cts:or-query()
, and apply that inside of a cts:and-query()
along with the cts:element-value-query()
for the $author-id
values:
declare namespace meta = "http://example.com/collection/book-metadata";
cts:search(doc(),
cts:and-query((
cts:element-value-query(xs:QName("meta:book-author"), $author-id),
cts:or-query((
cts:element-query(xs:QName("meta:date-added"), cts:true-query()),
cts:element-range-query(xs:QName("meta:newer-document-date"), "<", "$date-from")
))
))
)