How to return a collection of JSON documents as a JSON array

I have a collection of JSON documents in MarklLogic which I want to return to an API call as a JSON Array.

fn.collection('my-users')

Returns a sequence of JSON docs, I need a valid JSON object, an array. I am doing this in serverside java script, pushing to a new empty array().

No real example documentation to my knowledge, only in XQuery some examples.Google keeps referring to this very high level documentation here

var myArray = [];

for (d of fn.collection('my-users')){
  myArray.push(d);
}

myArray

Do I need to loop over each item in the sequence to push to an array or is there a more elegant/quicker solution?

hugo

Answers


Iterables are from ES6 and are (from what I understand), one of the only things carried over for the initial release of SJS along with sub-sequences.

The reason for these is so that you get the same behaviour as you would get with sequences and sub-sequences in xQuery. (different notation in the two languages, but identical behaviour)

If there were a full implementation of ES6, then the answer for you would be Array.from(iteratable)

However, without that feature, then I think you are using the most efficient way. But be careful that you don't suck your entire database into memory with the pushing from iterator to array.

I am curious of your use-case for needing them in an array actually..

-David


If you need to return them as a JSON array, you're doing the right thing. There's no more elegant/quicker solution that I know of. But if you're looking for a more optimized / high performance way, try REST extensions which will turn a sequence of documents into a multi-part HTTP response.

Here's an example. Given example.sjs with the contents:

function get(context, params) {
  return fn.collection('my-users')
}
exports.GET = get;

Installed like so:

curl --anyauth --user admin:admin -X PUT -i \
  -H "Content-type: application/vnd.marklogic-javascript" \
  --data-binary @./example.sjs \
  http://localhost:8000/LATEST/config/resources/js-example

And the following docs inserted into the my-users collection (I assume you know how to insert these):

myuser.json

{"name":"Sue"}

myuser2.json

{"name":"Mary"}

myuser3.json

{"name":"Jane"}

myuser4.json

{"name":"Joe"}

You can call your rest extension like so:

curl --anyauth --user admin:admin \
    http://localhost:8000/LATEST/resources/js-example

And you get the following multi-part http response:

--js-example-get-result
Content-Type: application/json
Content-Length: 14

{"name":"Sue"}
--js-example-get-result
Content-Type: application/json
Content-Length: 15

{"name":"Mary"}
--js-example-get-result
Content-Type: application/json
Content-Length: 15

{"name":"Jane"}
--js-example-get-result
Content-Type: application/json
Content-Length: 14

{"name":"Joe"}
--js-example-get-result--

Use your favorite client-side http library to accept that efficient response as an individual json document for each document.

I should add that there's no need for a REST extension if your requirements are this simple. You could simply use the REST search endpoint:

curl --anyauth --user admin:admin \
  -H accept:multipart/mixed \
  http://localhost:8000/LATEST/search?collection=my-users

and get a very similar multi-part http response. I only provided the REST extension example since your question was about server-side javascript and I figured you might have additional requirements that require that.


You don't have to loop. The following should help you for your need:

myArray.push(fn.doc(fn.collection('my-users')))


Need Your Help

What's the right way, for testability, to add functionality to a ComboBox?

c# .net winforms unit-testing testability

The desired functionality of the 'enhanced' combo box is a quick find method. Each item in the combobox has a ToString() method, such that they can be displayed in the drop down list. On clicking a...

Fixed top and left menu with reponsive design

html css html5 css3 responsive-design

I want to know if is it possible to create a theme with css where we can fixed the top and the left, and in the same time the theme must be responsive.