> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

# $function (expression operator)

## Definition

Defines a custom aggregation function or expression in JavaScript.

You can use the [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) operator to define custom functions to implement behavior not supported by the MongoDB Query Language. See also [`$accumulator`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator.md#mongodb-group-grp.-accumulator)

**Important:**

Executing JavaScript inside an aggregation expression may decrease performance. Only use the [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) operator if the provided [pipeline operators](https://www.mongodb.com/docs/manual/reference/mql/aggregation-stages.md#std-label-aggregation-pipeline-operator-reference) cannot fulfill your application's needs.

## Syntax

The [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) operator has the following syntax:

```javascript
{
  $function: {
    body: <code>,
    args: <array expression>,
    lang: "js"
  }
}
```

| Field | Type | Description |
| --- | --- | --- |
| [body](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#std-label-function-body) | String or Code | The function definition. You can specify the function definition as either BSON type Code or String. See also [lang.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#std-label-function-lang) `function(arg1, arg2, ...) { ... }` or `"function(arg1, arg2, ...) { ... }"` |
| [args](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#std-label-function-args) | Array | Arguments passed to the function [body](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#std-label-function-body). If the [body](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#std-label-function-body) function does not take an argument, you can specify an empty array `[ ]`. The array elements can be any BSON type, including Code. See [Example 2: Alternative to `$where`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#std-label-function-example-where-alternative) |
| [lang](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#std-label-function-lang) | String | The language used in the [body](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#std-label-function-body). You must specify `lang: "js"`. |

## Considerations

### Schema Validation Restriction

You cannot use [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) as part of a [schema validation](https://www.mongodb.com/docs/manual/core/schema-validation/specify-query-expression-rules.md#std-label-schema-validation-query-expression) query predicate.

### Javascript Enablement

To use [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function), you must have server-side scripting enabled (default).

If you do not use [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) (or [`$accumulator`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator.md#mongodb-group-grp.-accumulator), [`$where`](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where), or [`mapReduce`](https://www.mongodb.com/docs/manual/reference/command/mapreduce.md#mongodb-dbcommand-dbcmd.mapReduce)), disable server-side scripting:

- For a [`mongod`](https://www.mongodb.com/docs/manual/reference/program/mongod.md#mongodb-binary-bin.mongod) instance, see [`security.javascriptEnabled`](https://www.mongodb.com/docs/manual/reference/configuration-options.md#mongodb-setting-security.javascriptEnabled) configuration option or [`--noscripting`](https://www.mongodb.com/docs/manual/reference/program/mongod.md#std-option-mongod.--noscripting) command-line option.

- For a [`mongos`](https://www.mongodb.com/docs/manual/reference/program/mongos.md#mongodb-binary-bin.mongos) instance, see [`security.javascriptEnabled`](https://www.mongodb.com/docs/manual/reference/configuration-options.md#mongodb-setting-security.javascriptEnabled) configuration option or the [`--noscripting`](https://www.mongodb.com/docs/manual/reference/program/mongos.md#std-option-mongos.--noscripting) command-line option.

  In earlier versions, MongoDB does not allow JavaScript execution on
  [`mongos`](https://www.mongodb.com/docs/manual/reference/program/mongos.md#mongodb-binary-bin.mongos) instances.

See also [➤ Run MongoDB with Secure Configuration Options.](https://www.mongodb.com/docs/manual/administration/security-checklist.md#std-label-security-checklist-javascript)

### Alternative to `$where`

The query operator [`$where`](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where) can also be used to specify JavaScript expression. However:

- The [`$expr`](https://www.mongodb.com/docs/manual/reference/operator/query/expr.md#mongodb-query-op.-expr) operator allows the use of [aggregation expressions](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) within the query language.

- The [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) and [`$accumulator`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator.md#mongodb-group-grp.-accumulator) allows users to define custom aggregation expressions in JavaScript if the provided pipeline operators cannot fulfill your application's needs.

Given the available aggregation operators:

- The use of [`$expr`](https://www.mongodb.com/docs/manual/reference/operator/query/expr.md#mongodb-query-op.-expr) with aggregation operators that do not use JavaScript (i.e. non-[`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) and non-[`$accumulator`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator.md#mongodb-group-grp.-accumulator) operators) is faster than [`$where`](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where) because it does not execute JavaScript and should be preferred if possible.

- However, if you must create custom expressions, [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) is preferred over [`$where`.](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where)

### Unsupported Array and String Functions

MongoDB 6.0 upgrades the internal JavaScript engine used for [server-side JavaScript](https://www.mongodb.com/docs/manual/core/server-side-javascript.md#std-label-server-side-javascript), [`$accumulator`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator.md#mongodb-group-grp.-accumulator), [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function), and [`$where`](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where) expressions and from MozJS-60 to MozJS-91. Several deprecated, non-standard array and string functions that existed in MozJS-60 are removed in MozJS-91.

## Examples

### Example 1: Usage Example

Create a sample collection named `players` with the following documents:

```javascript
db.players.insertMany([
   { _id: 1, name: "Miss Cheevous",  scores: [ 10, 5, 10 ] },
   { _id: 2, name: "Miss Ann Thrope", scores: [ 10, 10, 10 ] },
   { _id: 3, name: "Mrs. Eppie Delta ", scores: [ 9, 8, 8 ] }
])
```

The following aggregation operation uses [`$addFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addfields.md#mongodb-pipeline-pipe.-addFields) to add new fields to each document:

- `isFound` whose value is determined by the custom [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) expression that checks whether the MD5 hash of the name is equal to a specified hash.

- `message` whose value is determined by the custom [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) expression that format a string message using a template.

```javascript
db.players.aggregate( [
   { $addFields:
      {
        isFound:
            { $function:
               {
                  body: function(name) {
                     return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad"
                  },
                  args: [ "$name" ],
                  lang: "js"
               }
            },
         message:
            { $function:
               {
                  body: function(name, scores) {
                     let total = Array.sum(scores);
                     return `Hello ${name}.  Your total score is ${total}.`
                  },
                  args: [ "$name", "$scores"],
                  lang: "js"
               }
            }
       }
    }
] )
```

The operation returns the following documents:

```javascript
{ "_id" : 1, "name" : "Miss Cheevous", "scores" : [ 10, 5, 10 ], "isFound" : false, "message" : "Hello Miss Cheevous.  Your total score is 25." }
{ "_id" : 2, "name" : "Miss Ann Thrope", "scores" : [ 10, 10, 10 ], "isFound" : true, "message" : "Hello Miss Ann Thrope.  Your total score is 30." }
{ "_id" : 3, "name" : "Mrs. Eppie Delta ", "scores" : [ 9, 8, 8 ], "isFound" : false, "message" : "Hello Mrs. Eppie Delta .  Your total score is 25." }
```

**Tip:**

Starting in MongoDB 8.3, you can use [`$hexHash`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/hexhash.md#mongodb-expression-exp.-hexHash) as a native aggregation alternative to `hex_md5`. `$hexHash` does not require server-side JavaScript and supports the SHA-256 and XXH64 algorithms in addition to MD5. Note that `$hexHash` returns an uppercase hexadecimal string, while `hex_md5` returns lowercase. MD5 is a legacy algorithm and is disabled in FIPS mode.

### Example 2: Alternative to `$where`

**Note: Aggregation Alternatives Preferred over $where**

The [`$expr`](https://www.mongodb.com/docs/manual/reference/operator/query/expr.md#mongodb-query-op.-expr) operator allows the use of [aggregation expressions](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) within the query language. And the [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) and [`$accumulator`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator.md#mongodb-group-grp.-accumulator) allows users to define custom aggregation expressions in JavaScript if the provided pipeline operators cannot fulfill your application's needs.

Given the available aggregation operators:

- The use of [`$expr`](https://www.mongodb.com/docs/manual/reference/operator/query/expr.md#mongodb-query-op.-expr) with aggregation operators that do not use JavaScript (i.e. non-[`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) and non-[`$accumulator`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/accumulator.md#mongodb-group-grp.-accumulator) operators) is faster than [`$where`](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where) because it does not execute JavaScript and should be preferred if possible.

- However, if you must create custom expressions, [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function) is preferred over [`$where`.](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where)

As an alternative to a query that uses the [`$where`](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where) operator, you can use [`$expr`](https://www.mongodb.com/docs/manual/reference/operator/query/expr.md#mongodb-query-op.-expr) and [`$function`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function). For example, consider the following [`$where`](https://www.mongodb.com/docs/manual/reference/operator/query/where.md#mongodb-query-op.-where) example.

```javascript
db.players.find( { $where: function() {
   return (hex_md5(this.name) == "15b0a220baa16331e8d80e15367677ad")
} } );
```

The [`db.collection.find()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.find.md#mongodb-method-db.collection.find) operation returns the following document:

```javascript
{ "_id" : 2, "name" : "Miss Ann Thrope", "scores" : [ 10, 10, 10 ] }
```

The example can be expressed using [`$expr`](https://www.mongodb.com/docs/manual/reference/operator/query/expr.md#mongodb-query-op.-expr) and [`$function`:](https://www.mongodb.com/docs/manual/reference/operator/aggregation/function.md#mongodb-expression-exp.-function)

```javascript
db.players.find( {$expr: { $function: {
      body: function(name) { return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad"; },
      args: [ "$name" ],
      lang: "js"
} } } )
```
