Warm tip: This article is reproduced from stackoverflow.com, please click
marklogic marklogic-9

Marklogic using xPath on managed documents results in all versions of this documents

发布于 2020-04-23 14:25:54


when using xpath on a managed (dls:document-insert-and-manage(...) ) document, I would like to use xpath expressions on this documents to retrieve only the actual document especially for other users.

With xpath I get either all versions of the document or no document.

I tried setting permissions on the document.
Restricting the URI is just for create.
Protecting the path does not help as the xpath is the same for all versions.

Is there a possibility to restrict this for some user to only get the latest Version?

We are using Marklogic 9.0.8

Example:

Setting a document with

xquery version "1.0-ml";
import module namespace dls = "http://marklogic.com/xdmp/dls" at "/MarkLogic/dls.xqy";

declare variable $uri :="/smtextdocuments/9114.xml";
declare variable $document := document {
<envelope>
  <instance>
    <smtextdocuments>
      <uri>/smtextdocuments/9114.xml</uri><id>9114</id>
      <documentcontent>MyText</documentcontent>
    </smtextdocuments>
  </instance>
</envelope>
};

let $d := dls:document-insert-and-manage($uri,fn:true(), $document,
        "Manage textdocuments",
        (
         xdmp:permission("dls-user", "read"),
         xdmp:permission("dls-internal", "read"),
         xdmp:permission("dls-internal", "update")),
        ()
        )
return $d

leads to either 2 or none elements when retrieving documents, depending on the permissions of the actual user

xquery version "1.0-ml";
<queryresult>
  <byxPath>{
    for $i in //smtextdocuments[id=9114]
    return (<uri>{fn:base-uri($i)}</uri>,$i)
    }
  </byxPath>
</queryresult>
Questioner
Franz B
Viewed
72
grtjn 2020-02-10 20:58

You are using DLS to store multiple versions of a document in parallel, so if you query the entire database (which is what happens if you use a bare absolute path like //xxx), you will get all matching versions of that document.

I would recommend switching to using cts:search, for instance in combination with the dls:documents-query(). If you also add in a path index for smtextdocuments/id, you can pinpoint your docs accurately:

import module namespace dls = "http://marklogic.com/xdmp/dls" 
  at "/MarkLogic/dls.xqy";

cts:search(collection(), cts:and-query((
  dls:documents-query(),
  cts:range-query(
    cts:path-reference('smtextdocuments/id'),
    '=',
    9114
  )
) 

HTH!