Search code examples
collectionsmarklogictde

How to do collections-not for TDE with Marklogic


I am looking to how to implement the collections-not for Marklogic TDE.

The equivalent one for the CTS query is

cts:not-query(cts:collection-query("archived"))

According to TDE documentation, it only supports AND, OR collections. I am looking for NOT collections with TDE schema.


Solution

  • EDIT: I changed the sample from: '.. = "include"..' to '... != "exclude"...' They both work. However, for the context of the question, not-equal makes more sense in an example.

    As odd as it seems, the feature that you are asking for is not available. However, there is a way to make use of the context that can help you. First of all, it is still good to set a collection or collection scope so that we minimize the sample set to analyze the context path.

    The approach is to use xPath and xQuery on the context as a filter.

    Below is a working sample for Query Console. Please not the ';' in the code as it is a multi-statement sample.

    xquery version "1.0-ml";
    
    let $_ := xdmp:document-insert("/llamas/Jalliue.xml", <llama><name>Jalliue</name></llama>, map:new()=>map:with("collections", ("llama", "include")))
    let $_ := xdmp:document-insert("/llamas/Sven.xml", <llama><name>Sven</name></llama>, map:new()=>map:with("collections", ("llama", "exclude")))
    return ();
    
    
    
    let $docs := (fn:doc("/llamas/Jalliue.xml"), fn:doc("/llamas/Sven.xml"))
    
    let $template := 
    <template xmlns="http://marklogic.com/xdmp/tde">
      <description>llama list</description>
      <context>/llama[xdmp:node-collections(.) != "exclude"]</context>
      <rows>
        <row>
          <schema-name>llama</schema-name>
          <view-name>list</view-name>
          <columns>
            <column>
              <name>name</name>
              <scalar-type>string</scalar-type>
              <val>name</val>
            </column>
          </columns>
        </row>
      </rows>
    </template>
    
    return tde:node-data-extract($docs, $template)
    

    The result shows that both documents were considered, but only the one with the collection "include" is parsed.

    {
      "/llamas/Jalliue.xml": [
        {
          "row": {
          "schema": "llama", 
          "view": "list", 
          "data": {
            "rownum": "1", 
            "name": "Jalliue"
            }
          }
        }
      ], 
      "/llamas/Sven.xml": []
    }