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

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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.