Using Cts Query to Retrieve Collections Associated with the Given Document Uri- Marklogic

I need to retrieve the collections to which a given document belongs in Marklogic. I know xdmp command does that. But I need to use it in cts query to retrieve the data and then filter records from it.

xdmp:document-get-collections("uri of document") can't be run inside cts-query to give appropriate data.

Any idea how can it be done using cts query?

Thanks

4 Answers

A few options come to mind:

Option One: Use cts:values()

cts:values(cts:collection-reference())

If you check out the documentation, you will see that you can also restrict this to certain fragments by passing a query as one of the parameters.

**Update: [11-10-2017] The comment attached to this asked for a sample of restricting the results of cts:values() to a single document(for practical purposes, I will say fragment == document)

The documentation for cts:values explains this. It is the 4th parameter - a query to restrict the results. Get to know this pattern as it is part of many features of MarkLogic. It is your friend. The query I would use for this problem statement would be a cts:document-query();

An Example:

cts:values(
  cts:collection-reference(), 
  (), 
  (), 
  cts:document-query('/path/to/my/document')
)

Full Example:

cts:search(
    collection(),
    cts:collection-query(
        cts:values(
          cts:collection-reference(), 
          (), 
          (), 
          cts:document-query('/path/to/my/document')
       )
    )
)[1 to 10]

Option two: use cts:collection-match()
Need more control over returning just some of the collections from a document, then use cts:colection-match(). Like the first option, you can restrict the results to just some fragments. However, it has the benefit of having an option for a pattern.


Attention:
They both return a sequence - perfect for feeding into other parts of your query. However, under the hood, I believe they work differently. The second option is run against a lexicon. The larger the list of unique collection names and the more complex your pattern match, the longer for resolution. I use collection-match in projects. However, I usually use it when I can limit the possible choices by restricting the results to a smaller number of documents.

2

You can't do this in a single step. You have to run code first to retrieve collections associated with a document. You can use something like xdmp:document-get-collections for that. You then have to feed that into a cts query that you build dynamically:

let $doc-collections := xdmp:document-get-collections($doc-uri)
return
  cts:search(collection(), cts:collection-query($doc-collections))[1 to 10]

HTH!

3

Are you looking for cts:collection-query()?

1

Insert two XML files to the same collection:

xquery version "1.0-ml";
xdmp:document-insert("/a.xml", <root><sub1><a>aaa</a></sub1></root>,
map:map() => map:with("collections", ("coll1")));

xdmp:document-insert("/b.xml", <root><sub2><a>aaa</a></sub2></root>,
map:map() => map:with("collections", ("coll1")));

Search the collection:

xquery version "1.0-ml";
let $myColl:= xdmp:document-get-collections("/a.xml")
return 
    cts:search(/root,
    cts:and-query((cts:collection-query($myColl),cts:element-query(xs:QName("a"),"aaa")
)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Sophia Al-Mansoor

Sophia Al-Mansoor

Global Business & E-Commerce Reporter

Sophia analyzes international trade, startup ecosystems, retail transformation, and supply chain logistics for modern digital publications.

Share this article
Twitter Facebook Pinterest