Copyright © 2015 Christian Grün and Dannes Wessels, published by the
This specification was published by the
This module provides an API for accessing the document database MongoDB. It defines functions to connect to the DBMS, retrieve documents from databases and collections, update resources, perform map-reduce queries, and execute server-side JavaScript functions and database commsands.
The module has been designed to be compatible with XQuery 3.1 and XPath 3.1, and
later versions. It has been inspired by existing
revisiondesc
This document is in an interim draft stage. Comments are welcomed at
The module defined by this document defines functions and errors in the
namespace http://expath.org/ns/mongo
. In this document, the
mongo
prefix is bound to this namespace URI. Error codes are
defined in the same namespace and are displayed with the same prefix.
The err
prefix denotes the namespace for XPath and XQuery errors,
http://www.w3.org/2005/xqt-errors
, as defined in the
Error conditions are identified by a code (a QName
). When such
an error condition is reached in the evaluation of an expression, a dynamic
error is thrown, with the corresponding error code (as if the standard XPath
function error()
had been called).
The following errors apply to most functions of this specification:
/\. "$*<>:|?
Since Version 3.1, maps and arrays are available in XQuery and XPath. This specification makes heavy use of the feature: all JSON objects and arrays are represented in the equivalent XQuery data types.
If JSON strings are preferred as input and output, the functions
fn:parse-json
and fn:serialize
of the
The next example shows how XQuery maps can be serialized as JSON:
All functions in this module are ·nondeterministic·. Non-deterministic functions may return different results when executed more than once. This is illustrated by two examples:
The
Calling
A query processor must ensure that non-deterministic functions are not relocated or rewritten in the query, and that its results are not cached at runtime.
A
mongo:connect
Establishes a connection to MongoDB and returns a client id as string that identifies the opened connection.
The $uri
string follows the MongoDB URI format. It must
at least contain one host name, and it may be prefixed with the
mongo
scheme and suffixed with a port number.
Multiple hosts, e.g. for a replica set, are separated with commas.
The format of the returned client id string is implementation-defined, but all returned ids must be unique during the evaluation of a query.
The following expression creates three connections to local MongoDB
instances, using the default port, and returns the client ids as result:
The following function call connects to a replica set with three members,
and distributes reads to the secondary:
mongo:list-databases
Returns the names of all databases on the connected server.
The connection is identified by the supplied $client-id
.
The following query lists all databases on localhost:
mongo:close
Closes an open database connection. The connection to be closed is
identified by the supplied $client-id
. When a database connection
is closed, the associated id is discarded and invalidated. As a consequence,
each database can be closed once.
A connection must be kept open as long as it has not explicitly been closed by the user, and as long as the query has not been fully evaluated. After query evaluation, an implementation must ensure that all remaining connections are automatically closed.
The following expression closes a connection that has just been opened:
The module provides no function for creating new databases, because non-existing databases will automatically be created by MongoDB with the first write operation.
mongo:list-collections
Returns the names of all collections contained in a databases.
The connection is identified by the supplied $client-id
,
and the name of the database is supplied via $database
.
mongo:command
Executes a $command
, and returns the result as a map.
The connection is identified by the supplied $client-id
,
and the name of the database is supplied via $database
.
The object returned by MongoDB contains the field ok
, which
must be parsed by the implementation to decide if command execution was
successful (indicated by the integer value 1
) or not
(0
). The field must be removed from the object before the
result is returned as map. If execution failed, the field
errmsg
can be parsed to return a proper error message.
The following query clones a database from a remote MongoDB instance to
the current host. The result will either be a map, which contains the
result of the command execution, or an error:
mongo:eval
Runs server-server JavaScript script code, supplied via $code
.
Function arguments can be supplied via $args
. Arguments can
be booleans, strings, numbers, arrays or maps. An error will be raised if
any other type is supplied.
Items of type xs:untypedAtomic are converted to strings.
The connection is identified by the supplied $client-id
,
and the name of the database is supplied via $database
.
Due to the different type systems of XQuery and JavaScript, it is not possible to losslessly convert all values to one language and back. To ensure compatibility, an implementation must obey the following conversion rules:
Conversion of XQuery arguments to JavaScript:
A value of type xs:boolean is converted to a boolean. A value of type xs:string and xs:untypedAtomic are converted to a
string. A value of type xs:numeric is converted to a number (i.e. a
double-precision floating-point format value). A value of type map(*) is converted to an object. Its entries must
be converted recursively according to the given rules. A value of type array(*) is converted to an array. Its members must
be converted recursively according to the given rules. The error
Conversion of JavaScript results to XQuery:
A boolean is converted to xs:boolean. A string is converted to xs:string. A number is converted to xs:double. An object is converted to map(*). Its entries must be converted
recursively according to the given rules. An array is converted to array(*). Its members must be converted
recursively according to the given rules. The error
The following query returns the result of an arithmetic expression:
mongo:drop-database
Drops a database. No operation will be performed if the database does not exist.
The connection is identified by the supplied $client-id
,
and the name of the database is supplied via $database
.
The following query drops five databases (provided they exist):
mongo:find
Returns documents of a collection. If a query is supplied via the
$query
argument, the documents are filtered by that query.
The $options
argument can have the following entries:
"fields": map(*)
: Restricts the returned fields.
The field _id
will always be returned."sort": map(*)
: Sorts the returned documents."limit": xs:integer
: Limits the number of returned
documents by the specified integer."skip": xs:integer
: Skips the number of specified
documents.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following expression queries an addressbook and selects all persons living in Tokyo. It sorts results by the names and returns the first 50 documents:
mongo:find-one
Returns the first document of a database that optionally matches a
supplied $query
.
The $options
argument can have have the following entries:
"fields": map(*)
: Restricts the returned fields.
The field _id
will always be returned.
"sort": map(*)
: Sorts the documents before returning
the first result.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following query returns the first document that matches the specified query:
mongo:count
Counts documents in a collection. If a query is supplied via the
$query
argument, the documents are filtered by that query.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following expression counts the number of documents in the "addressbook" collection:
mongo:aggregate
Calculates aggregate values for the documents in a collection and returns
the results. The operations to be performed are supplied via
the $pipeline
argument.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following query selects all documents with "Tokyo" as city and returns their names:
mongo:group
Groups documents in a collection by the supplied $fields
,
aggregates the documents via the $reduce
function, and
returns the results. $initial
provides an initial result
document, which will be modified by the reduce function.
The $options
argument can have the following entries:
"cond": map(*)
: Filters the documents before being
processed."finalize": xs:string
: Follows the reduce function
and modifies the output.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following groups documents with age > 60 by the city field and returns the summed up orders field:
mongo:map-reduce
Runs a map-reduce aggregation operation over the documents of a
collection. The map and reduce functions are supplied via the
$map
and $reduce
arguments.
The $options
argument can have the following entries:
"query": map(*)
: Filters the documents before being
processed."output": xs:string
: Specifies the output target
of the result."type": xs:string
: Specifies the output type. Allowed
values are INLINE
(default), REPLACE
,
MERGE
and REDUCE
."finalize": xs:string
: Follows the reduce function
and modifies the output."sort": map(*)
: Sorts the returned documents."limit": xs:integer
: Limits the number of returned
documents by the specified integer.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following query sums up the numbber of orders from all documents of the "addressbook" collection:
mongo:find-and-modify
Finds a document that has been selected via the $query
argument, modifies it according to the $update
argument, and
returns the document as it was before the modifications. An empty sequence
is returned if no document was found.
The $options
argument can have the following entries:
"fields": map(*)
: Restricts the returned fields.
The field _id
will always be returned.
"sort": map(*)
: Sorts the documents before choosing the
first one as candidate for modification.
"new": xs:boolean
: Returns the modified document
rather than the original.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following query modifies a document with the specified id:
mongo:find-and-remove
Finds a document that has been selected via the $query
argument and returns it after removing it from the database. An empty
sequence is returned if no document was found.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following query removes a document with the specified id:
mongo:insert
Inserts documents into a collection. If the collection does not exists on
the server, it will be created. If the new document does not contain an
_id
field, it will be added.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following expression inserts two new documents into a collection:
mongo:save
Updates an existing document in a collection or inserts a new document.
If the supplied document has no _id
field, or if the id does
not exist in the collection, the document will be inserted. Otherwise,
the existing document will be replaced.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following expression updates or inserts a single document:
mongo:update
Finds one or more document that have been selected via the
$query
argument and modifies them according to the
$update
argument.
The $options
argument can have have the following entries:
"upsert": xs:boolean
: Inserts a new document if no
document matches the query criteria.
"multi": xs:boolean
: Updates all documents in the
collection that match the update query. Otherwise, updates only
one document.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following update applies to all documents in the addressed collection.
It replaces the value of the info
field with null
,
or adds a new name/value pair if the field does not exist:
mongo:remove
Removes documents from a collection that are selected by the
$query
argument.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following expression removes all documents from a collection:
mongo:drop-collection
Drops a collection. No operation will be performed if the collection does not exist.
The connection is identified by the supplied $client-id
,
and the name of the database and collection are supplied via
$database
and $collection
.
The following query drops five collections in a database: