Definición
$functionDefine una función o expresión de agregación personalizada en JavaScript.
Puedes utilizar el
$functionOperador para definir funciones personalizadas que implementen comportamientos no compatibles con el lenguaje de consulta MongoDB. Véase también$accumulator.Importante
Ejecutar JavaScript dentro de una expresión de agregación puede reducir el rendimiento. Utilice el
$functionoperador solo si los operadores de canalización proporcionados no satisfacen las necesidades de su aplicación.
Sintaxis
El operador $function tiene la siguiente sintaxis:
{ $function: { body: <code>, args: <array expression>, lang: "js" } }
Campo | Tipo | Descripción |
|---|---|---|
Cadena o código | Definición de la función. Puede especificar la definición de la función como código o cadena de tipo BSON. Véase también lang.
or
| |
Arreglo | Argumentos pasados al cuerpo de la función. Si el cuerpo de la función no acepta ningún argumento, se puede especificar una matriz Los elementos de la matriz pueden ser de cualquier tipo BSON, incluido Code. Véase el 2Ejemplo: Alternativa | |
String | El idioma utilizado en el cuerpo. Debe |
Considerations
Restricción de validación de esquema
No se puede utilizar como parte $function de un predicado de consulta de validación de esquema.
Javascript Enablement
Para utilizar, debe tener habilitadas las secuencias de comandos del lado del servidor $function (predeterminado).
Si no utiliza $function (o, o), deshabilite las secuencias de comandos del lado del $accumulator $where mapReduceservidor:
Para una instancia de
mongod, consulta la opción de configuraciónsecurity.javascriptEnabledo la opción de línea de comandos--noscripting.Para una instancia
mongos, consulta la opción de configuraciónsecurity.javascriptEnabledo la opción de línea de comandos--noscripting.In earlier versions, MongoDB does not allow JavaScript execution onmongosinstances.
Consulta también ➤ Ejecutar MongoDB con opciones de configuración seguras.
Alternativa a $where
El operador de consulta también se puede usar para especificar expresiones JavaScript. Sin $where embargo:
El operador permite
$exprel uso de expresiones de agregación dentro del lenguaje de consulta.$functiony permiten a los usuarios definir expresiones de agregación personalizadas en JavaScript si los operadores de canalización proporcionados no pueden satisfacer las necesidades de su$accumulatoraplicación.
Dado los operadores de agregación disponibles:
El uso de con operadores de agregación que
$expr$function$accumulatorno utilizan JavaScript (es decir, operadores que no son ni) es más rápido que$whereporque no ejecuta JavaScript y debería preferirse si es posible.Sin embargo, si es necesario crear expresiones personalizadas,
$functiones preferible a$where.
Funciones de string y arreglo no compatibles
MongoDB 6.0 actualiza el motor JavaScript interno utilizado para JavaScript del lado del servidor, expresiones, $accumulator $functiony, y de $where MozJS-60 a91 MozJS-. Varias funciones de matriz y cadena obsoletas y no estándar que existían en MozJS-60 se eliminan en MozJS-.91
Ejemplos
Ejemplo 1: Ejemplo de uso
Cree una colección de muestra denominada players con los siguientes documentos:
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 ] } ])
La siguiente operación de agregación utiliza para agregar nuevos campos a cada $addFields documento:
isFoundcuyo valor está determinado por la$functionexpresión personalizada que verifica si el5 hash MD del nombre es igual a un hash especificado.messagecuyo valor está determinado por la$functionexpresión personalizada que formatea un mensaje de cadena utilizando una plantilla.
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" } } } } ] )
La operación devuelve los siguientes documentos:
{ "_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." }
Ejemplo 2: Alternativa a $where
Nota
Alternativas de agregación preferidas sobre $where
El $expr operador permite el uso de expresiones de agregación dentro del lenguaje de consulta. Los $function operadores y permiten a los usuarios definir expresiones $accumulator de agregación personalizadas en JavaScript si los operadores de canalización proporcionados no satisfacen las necesidades de su aplicación.
Dado los operadores de agregación disponibles:
El uso de con operadores de agregación que
$expr$function$accumulatorno utilizan JavaScript (es decir, operadores que no son ni) es más rápido que$whereporque no ejecuta JavaScript y debería preferirse si es posible.Sin embargo, si es necesario crear expresiones personalizadas,
$functiones preferible a$where.
Como alternativa a una consulta que utiliza el operador,$where puede usar y. Por $expr ejemplo, considere el $function $where siguiente ejemplo.
db.players.find( { $where: function() { return (hex_md5(this.name) == "15b0a220baa16331e8d80e15367677ad") } } );
La operación devuelve el siguiente db.collection.find() documento:
{ "_id" : 2, "name" : "Miss Ann Thrope", "scores" : [ 10, 10, 10 ] }
El ejemplo se puede expresar utilizando $expr $functiony:
db.players.find( {$expr: { $function: { body: function(name) { return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad"; }, args: [ "$name" ], lang: "js" } } } )