Definición
$functionDefine una función o expresión de agregación personalizada en JavaScript.
Puedes usar el operador
$functionpara definir funciones personalizadas e implementar comportamientos no admitidos por el languaje del query de MongoDB. Véase también$accumulator.Importante
La ejecución de JavaScript dentro de una expresión de agregación puede reducir el rendimiento. Solo utilice el operador
$functionsi los operadores de pipeline proporcionados no pueden cumplir con 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 a la función body. Si la función body no recibe ningún argumento, puedes especificar un arreglo vacío Los elementos del arreglo pueden ser de cualquier tipo BSON, incluyendo Code. Consulta Ejemplo 2: Alternativa a | |
String | El idioma utilizado en el cuerpo. Debe |
Considerations
Restricción de validación de esquema
No puedes usar $function como parte de la validación del esquema expresión de consulta.
Javascript Enablement
Para utilizar, debe tener habilitadas las secuencias de comandos del lado del servidor $function (predeterminado).
Si no utilizas $function (o $accumulator, $where o mapReduce), desactiva los scripts en el lado del servidor:
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
$exprcon operadores de agregación que no usan JavaScript (es decir, no son-$functionni son-$accumulatoroperadores) es más rápido que$whereporque no ejecuta JavaScript y debe 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
Para obtener la lista completa de funciones de arreglo y string eliminadas, consulta las notas de compatibilidad 6.0.
Ejemplos
Ejemplo 1: Ejemplo de uso
Crea una colección de muestra llamada 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 $addFields para añadir nuevos campos a cada documento:
isFoundcuyo valor se determina mediante la expresión personalize$functionque comprueba si el hash MD5 del nombre es igual a un hash especificado.messagecuyo valor es determinado por la expresión personalizada$functionque formatea un mensaje de string 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 languaje del query. El $function y el $accumulator permiten a los usuarios definir expresiones de agregación personalizadas en JavaScript si los operadores de pipeline proporcionados no pueden satisfacer las necesidades de su aplicación.
Dado los operadores de agregación disponibles:
El uso de
$exprcon operadores de agregación que no usan JavaScript (es decir, no son-$functionni son-$accumulatoroperadores) es más rápido que$whereporque no ejecuta JavaScript y debe preferirse si es posible.Sin embargo, si es necesario crear expresiones personalizadas,
$functiones preferible a$where.
Como alternativa a una query que utiliza el operador $where, puedes utilizar $expr y $function. Por ejemplo, considere el siguiente $where ejemplo.
db.players.find( { $where: function() { return (hex_md5(this.name) == "15b0a220baa16331e8d80e15367677ad") } } );
La operación db.collection.find() devuelve el siguiente 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" } } } )