callow
callow

Reputation: 517

Creating a global map variable in xquery library module in Marklogic

I need to add a map to a library module. The map's used by most of its functions. I have a function that populates the map.

declare variable $map as map:map :=local:populateMap();

declare function local:populateMap() {
  let $map:=map:map()
   let $dummy1:=for $id in cts:search(/document/id,cts:element-query(xs:QName("document"),cts:and-query(())),"unfiltered" )
      let $dummy2:=map:put($map,$id/fn:string(),someValueCorrespondingToCurrentId)
       return ()
   return $map     

};

other functions that use the map

My documents look like this:

<document>
 <id>id</id>
<otherElements>
 ...........
</otherElements> 
</document>

The code inside local:populateMap() looks a bit awkward to me especially for the use of those dummy variables. What would be a better approach to do this?

Upvotes: 2

Views: 756

Answers (2)

dirkk
dirkk

Reputation: 6218

If find the following syntax much more readable and more in style with a functional programming language:

declare function local:populateMap() {
  map:new((
    for $id in cts:search(/document/id,cts:element-query(xs:QName("document"),cts:and-query(())),"unfiltered" )
    return map:entry($id/string(), someValueCorrespondingToCurrentId)
  ))
};

This code creates a new map with the given map entries. In the code sample you provided for each iteration a new map should be created.

Upvotes: 1

Dave Cassel
Dave Cassel

Reputation: 8422

Suppose you have a path range index on /document/id:

declare function local:populateMap() {
  map:new((
    cts:values(
      cts:path-reference("/document/id"))
    ) ! map:entry(., someValueCorrespondingToCurrentId)
  ))
};

Suppose someValueCorrespondingToCurrentId is something that comes from the same document as the id and also has a range index on it.

declare function local:populateMap() {
  map:new((
    cts:values(cts:path-reference("/document/id"))) ! 
      map:entry(., 
        cts:values(
          cts:SOMETHING-reference(
            reference-spec, 
            (), 
            "limit=1", 
            cts:path-range-query("/document/id", "=", .)
          )
        )
      )
  ))
};

The "!" operator concisely replaces your inner FLWOR, while map:new and map:entry replace the outer one. In the second code block above, I'm looking up the cts:*-reference that occurs in the same document as the current id. In both cases, all values are retrieved from indexes, so documents don't need to be loaded from disk.

Upvotes: 1

Related Questions