Definición
$functionImportante
JavaScript del lado del servidor está obsoleto
A partir de MongoDB 8.0, las funciones de JavaScript del lado del servidor (
$accumulator,$function,$where) son obsoletas. MongoDB registra una advertencia cuando se ejecutan estas funciones.Define una función o expresión de agregación personalizada en JavaScript.
Puedes utilizar el operador
$functionpara definir funciones personalizadas que implementen comportamientos no admitidos por el languaje del query de MongoDB. Ver 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 |
|---|---|---|
string o código | La definición de la función. Puedes especificar la definición de la función como tipo BSON Code o String. Consulte también idioma.
or
| |
Arreglo | Argumentos pasados la función de body. Si la función body no recibe un argumento, se puede especificar un arreglo vacío Los elementos del arreglo pueden ser de cualquier tipo BSON, incluyendo Code. Consulta Ejemplo 2: Alternativa a | |
String | El lenguaje utilizado en el cuerpo. Debe especificar |
Considerations
Restricción de validación de esquema
No puedes usar $function como parte de un predicate de validación de esquemas.
Javascript Enablement
Para usar $function, debes tener habilitados los scripts del lado del servidor (por defecto).
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.En versiones anteriores, MongoDB no permite la ejecución de JavaScript en instancias de
mongos.
Consulta también ➤ Ejecutar MongoDB con opciones de configuración seguras.
Alternativa a $where
El operador del query $where también puede utilizarse para especificar expresiones de JavaScript. Sin embargo:
El operador
$exprpermite el uso de expresiones de agregación dentro del lenguaje de la query.El
$functiony$accumulatorpermiten a los usuarios definir expresiones de agregación personalizadas en JavaScript si los operadores proporcionados del pipeline no pueden satisfacer las necesidades de tu 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.
Funciones de string y arreglo no compatibles
MongoDB 6.0 actualiza el motor interno de JavaScript utilizado para JavaScript del lado del servidor, $accumulator, $function y $where expresiones, pasando de MozJS-60 a MozJS-91. Varias funciones de arreglos y strings obsoletas y no estándar que existían en MozJS-60 se eliminan en MozJS-91.
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." }
Tip
A partir de MongoDB 8.3, puedes utilizar $hexHash como una alternativa nativa de agregación a hex_md5. $hexHash no requiere JavaScript en el lado del servidor y admite los algoritmos SHA-256 y XXH64 además de MD5. Tenga en cuenta que $hexHash devuelve una string hexadecimal en mayúsculas, mientras que hex_md5 devuelve en minúsculas. MD5 es un algoritmo heredado y está desactivado en el modo FIPS.
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. Y la $function y $accumulator permite a los usuarios definir expresiones de agregación personalizadas en JavaScript si los operadores de pipeline proporcionados no pueden satisfacer las necesidades de tu 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.
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 puede expresarse usando $expr y $function:
db.players.find( {$expr: { $function: { body: function(name) { return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad"; }, args: [ "$name" ], lang: "js" } } } )