Native Operations MongoDB Syntax
Native Queries
Pipeline to include in MongoDB queries. For details on how to write an aggregation pipeline see https://www.mongodb.com/docs/manual/core/aggregation-pipeline/
The pipeline may include Extended JSON.
Keys and values in the pipeline may contain placeholders of the form {{variableName}}
which will be substituted when
the native query is executed according to the given arguments.
Placeholders must be inside quotes so that the pipeline can be stored in JSON format. If the pipeline includes a string whose only content is a placeholder, when the variable is substituted the string will be replaced by the type of the variable. For example in this pipeline,
[
{
"$documents": "{{ documents }}"
}
]
If the type of the documents
argument is an array then after variable substitution the pipeline will expand to:
[
{
"$documents": [
/* array of documents */
]
}
]
Examples
Collection Representation
{
"name": "ArtistWAlbumCount",
"representation": "collection",
"inputCollection": "Artist",
"description": "Artists including their album count",
"arguments": {},
"resultDocumentType": "ArtistWAlbumCount",
"objectTypes": {
"ArtistWAlbumCount": {
"fields": {
"ArtistId": {
"type": {
"scalar": "int"
}
},
"Name": {
"type": {
"scalar": "string"
}
},
"AlbumCount": {
"type": {
"scalar": "int"
}
},
"_id": {
"type": {
"scalar": "objectId"
}
}
}
}
},
"pipeline": [
{
"$lookup": {
"from": "Album",
"localField": "ArtistId",
"foreignField": "ArtistId",
"as": "Albums"
}
},
{ "$unwind": "$Albums" },
{
"$group": {
"_id": "$ArtistId",
"id": { "$first": "$_id" },
"Name": { "$first": "$Name" },
"AlbumCount": { "$count": {} }
}
},
{
"$project": {
"_id": "$id",
"ArtistId": "$_id",
"Name": 1,
"AlbumCount": 1
}
}
]
}
Function Representation
{
"name": "hello",
"representation": "function",
"description": "Basic test of native queries",
"arguments": {
"name": { "type": { "scalar": "string" } }
},
"resultDocumentType": "Hello",
"objectTypes": {
"Hello": {
"fields": {
"__value": { "type": { "scalar": "string" } }
}
}
},
"pipeline": [
{
"$documents": [
{
"__value": "{{ name }}"
}
]
}
]
}
Documentation
Name
Property | Required? |
---|---|
"name" | Yes |
Represents the name of the query that is exposed in your API.
Representation
Property | Required? |
---|---|
"representation" | Yes |
Using a representation of a function in MongoDB Native Queries follows the same requirements of functions in the DDN spec. Specifically:
A function is a collection which returns a single row and a single column, named __value
Refer to the function example above.
There are 2 options:
collection
is used here in terms of DDN collections.function
is used here in terms of DDN functions.
Native queries with the function
representation have the restriction that the aggregation pipeline output must be a
singe document with a single property named __value
. When the function is invoked the document will be unwrapped, and
the value in __value
will be used as the return value of the function. This allows functions to produce values that
are not objects, as opposed to MongoDB aggregation pipelines which can only produce streams of objects.
Input Collection
Property | Required? |
---|---|
"inputCollection" | No |
Determines how the pipeline is run. If "inputCollection"
is present then the pipeline runs with that collection as the
starting point. It is the same as doing db.artist.aggregate
in mongosh
. If no "inputCollection"
is present then
the pipeline is run with db
as the starting point. Which is the same as doing db.aggregate
in mongosh
.
Description
Property | Required? |
---|---|
"description" | No |
Used for documentation purposes in the API.
Arguments
Property | Required? |
---|---|
"arguments" | No |
Used if you want to accept arguments in your API for your pipeline. Please refer to Types. Arguments are
denoted in your pipeline code using "{{ argument }}"
.
Example:
"arguments": {
"abs": {
"type": {
"scalar": "int"
}
},
"binarySize": {
"type": {
"scalar": "string"
}
}
Result Document Type
Property | Required? |
---|---|
"resultDocumentType" | Yes |
Represents the result type of your pipeline. This can refer to an existing object type from your schema or can be object types you write yourself following the structure of Types
A pipeline returns a stream of documents. resultDocumentType
is the type of each individual document.
Object Types
Property | Required? |
---|---|
"objectTypes" | No |
If you need to return a type that is not already in your schema then you can write your own. Please refer to Types on how to write your own object types. The only difference is those types need to be wrapped in a type name followed by fields.
Object types from all configuration files occupy a shared namespace so it is important that object type names be unique within your configuration.
Example:
"objectTypes": {
"ArtistWAlbumCount": {
"fields": {
"ArtistId": {
"type": {
"scalar": "int"
}
},
"Name": {
"type": {
"scalar": "string"
}
},
"AlbumCount": {
"type": {
"scalar": "int"
}
},
"_id": {
"type": {
"scalar": "objectId"
}
}
}
}
}
Pipeline
Property | Required? |
---|---|
"pipeline" | Yes |
The pipeline is almost identical to what you would write in javascript or mongosh using the aggregate
pipeline API. The only difference is the double qouted keys to comply with JSON. For documentation
on aggregate pipelines please refer to MongoDB. If you have arguments they need to be wrapped in
double quotes and double braces "{{ argument }}"
. See example with arguments below.
Example: without arguments
"pipeline": [
{
"$lookup": {
"from": "Album",
"localField": "ArtistId",
"foreignField": "ArtistId",
"as": "Albums"
}
},
{"$unwind": "$Albums"},
{
"$group": {
"_id": "$ArtistId",
"id": {"$first": "$_id"},
"Name": {"$first": "$Name"},
"AlbumCount": {"$count": {}}
}
},
{
"$project": {
"_id": "$id",
"ArtistId": "$_id",
"Name": 1,
"AlbumCount": 1
}
}
]
Example: with arguments
"pipeline": [
{
"$documents": [
{
"__value": {
"abs": {
"$abs": "{{ abs }}"
},
"binarySize": {
"$binarySize": "{{ binarySize }}"
},
"ceil": {
"$ceil": "{{ ceil }}"
},
"floor": {
"$floor": "{{ floor }}"
},
"divide": {
"$divide": ["{{ dividend }}", "{{ divisor }}"]
}
}
}
]
}
]
Types
Each field in a JSON object is defined with a key specifying the name of the field. Below the key, the "type" is specified, which can be a scalar or structural type, followed by the type name. Here are descriptions for each type:
Scalar Types
- double: Represents a floating point number.
- string: Represents a sequence of characters.
- bool: Represents a boolean value, true or false.
- int: Represents an integer.
- long: Represents a longer form of integer.
- decimal: Represents a large decimal number.
- date: Represents a date, stored as a string in ISO format.
- timestamp: Represents a Unix timestamp.
- objectId: Represents an object identifier.
Structural Types
- object: Represents a BSON document or an embedded document. Users can define their own nested object types, specifying the structure of these objects as required by their applications.
- arrayOf: Represents an array of elements, with each element being a type specified after "arrayOf". For instance, "arrayOf": "string" means an array of strings.
Examples:
{
"age": {
"type": {
"scalar": "int"
}
},
"name": {
"type": {
"scalar": "string"
}
},
"preferences": {
"type": {
"object": "userPreferences"
}
},
"tags": {
"type": {
"arrayOf": "string"
}
},
"employment": {
"type": {
"object": "employmentDetails"
}
}
}
In this example:
- age is an integer.
- name is a string.
- preferences is a complex object defined elsewhere as userPreferences, indicating a structured type defined by the user.
- tags is an array consisting of strings.
- employment is a user-defined object type employmentDetails, which would be specified in more detail elsewhere in the documentation.
Native Mutations
Command to run via MongoDB's runCommand
API. For details on how to write commands see
https://www.mongodb.com/docs/manual/reference/method/db.runCommand/
The command is read as Extended JSON. It may be in canonical or relaxed format, or a mixture of both. See https://www.mongodb.com/docs/manual/reference/mongodb-extended-json/
Keys and values in the command may contain placeholders of the form {{variableName}}
which will be substituted when
the native procedure is executed according to the given arguments.
Placeholders must be inside quotes so that the command can be stored in JSON format. If the command includes a string whose only content is a placeholder, when the variable is substituted the string will be replaced by the type of the variable. For example in this command,
{
"insert": "posts",
"documents": "{{ documents }}"
}
If the type of the documents
argument is an array then after variable substitution the command will expand to:
{
"insert": "posts",
"documents": [
/* array of documents */
]
}
Examples
Insert
"name": "insertArtist",
"description": "Example of a database insert using a native mutation",
"resultType": {
"object": "InsertArtist"
},
"arguments": {
"artistId": {
"type": {
"scalar": "int"
}
},
"name": {
"type": {
"scalar": "string"
}
}
},
"objectTypes": {
"InsertArtist": {
"fields": {
"ok": {
"type": {
"scalar": "int"
}
},
"n": {
"type": {
"scalar": "int"
}
}
}
}
},
"command": {
"insert": "Artist",
"documents": [
{
"ArtistId": "{{ artistId }}",
"Name": "{{ name }}"
}
]
}
}
Update
{
"name": "updateArtist",
"description": "Example of a database update using a native mutation",
"resultType": {
"object": "UpdateArtist"
},
"arguments": {
"artistId": {
"type": {
"scalar": "int"
}
},
"name": {
"type": {
"scalar": "string"
}
}
},
"objectTypes": {
"UpdateArtist": {
"fields": {
"ok": {
"type": {
"scalar": "int"
}
},
"n": {
"type": {
"scalar": "int"
}
}
}
}
},
"command": {
"update": "Artist",
"updates": [
{
"q": {
"ArtistId": "{{ artistId }}"
},
"u": {
"ArtistId": "{{ artistId }}",
"Name": "{{ name }}"
}
}
]
}
}
Delete
{
"name": "deleteArtist",
"description": "Example of a database delete using a native mutation",
"resultType": {
"object": "DeleteArtist"
},
"arguments": {
"artistId": {
"type": {
"scalar": "int"
}
}
},
"objectTypes": {
"DeleteArtist": {
"fields": {
"ok": {
"type": {
"scalar": "int"
}
},
"n": {
"type": {
"scalar": "int"
}
}
}
}
},
"command": {
"delete": "Artist",
"deletes": [
{
"q": {
"ArtistId": "{{ artistId }}"
}
}
]
}
}
Documentation
Name
"name"
: Required
Represents the name of the query that is exposed in your API.
Description
"description"
: Optional
Used for documentation purposes in the API.
Result Type
"resultType"
: Required
Represents the result type of your command. This can refer to an existing object type from your schema or can be an object type you write in the native query file following the structure of Types
Arguments
"arguments"
: Optional
Used if you want to accept arguments in your API for your command. Please refer to Types. Arguments are
denoted in your command code using "{{ argument }}"
.
Example:
"arguments": {
"age": {
"type": {
"scalar": "int"
}
},
"name": {
"type": {
"scalar": "string"
}
}
}
Object Types
"objectTypes"
: Optional
If you need to return a type that is not already in your schema then you can write your own. Please refer to Types on how to write your own object types. The only difference is those types need to be wrapped in a type name followed by fields.
Example:
"objectTypes": {
"ArtistWAlbumCount": {
"fields": {
"ArtistId": {
"type": {
"scalar": "int"
}
},
"Name": {
"type": {
"scalar": "string"
}
},
"AlbumCount": {
"type": {
"scalar": "int"
}
},
"_id": {
"type": {
"scalar": "objectId"
}
}
}
}
}
Command
"command"
: Required
The command is almost identical to what you would write in javascript or mongosh using the
runCommand API. The only difference is the double qouted keys to comply with JSON. For
documentation on runCommand please refer to MongoDB. If you have arguments they need to be
wrapped in double quotes and double braces "{{ argument }}"
. See example below.
Example:
"command": {
"insert": "Artist",
"documents": [
{
"ArtistId": "{{ artistId }}",
"Name": "{{ name }}"
}
]
}
Types
Each field in a JSON object is defined with a key specifying the name of the field. Below the key, the "type" is specified, which can be a scalar or structural type, followed by the type name. Here are descriptions for each type:
Scalar Types
- double: Represents a floating point number.
- string: Represents a sequence of characters.
- bool: Represents a boolean value, true or false.
- int: Represents an integer.
- long: Represents a longer form of integer.
- decimal: Represents a large decimal number.
- date: Represents a date, stored as a string in ISO format.
- timestamp: Represents a Unix timestamp.
- objectId: Represents an object identifier.
Structural Types
- object: Represents a BSON document or an embedded document. Users can define their own nested object types, specifying the structure of these objects as required by their applications.
- arrayOf: Represents an array of elements, with each element being a type specified after "arrayOf". For instance, "arrayOf": "string" means an array of strings.
Examples:
{
"age": {
"type": {
"scalar": "int"
}
},
"name": {
"type": {
"scalar": "string"
}
},
"preferences": {
"type": {
"object": "userPreferences"
}
},
"tags": {
"type": {
"arrayOf": "string"
}
},
"employment": {
"type": {
"object": "employmentDetails"
}
}
}
In this example:
- age is an integer.
- name is a string.
- preferences is a complex object defined elsewhere as userPreferences, indicating a structured type defined by the user.
- tags is an array consisting of strings.
- employment is a user-defined object type employmentDetails, which would be specified in more detail elsewhere in the documentation.