Definição
$functionImportante
JavaScript do lado do servidor obsoleto
A partir do MongoDB 8.0, as funções JavaScript do lado do servidor (
$accumulator,$function,$where) estão obsoletas. O MongoDB registra um alerta quando você executa essas funções.Define uma função de agregação personalizada ou expressão em JavaScript.
Você pode usar o operador
$functionpara definir funções personalizadas para implementar comportamentos não compatíveis com a linguagem de query do MongoDB . Consulte também$accumulator.Importante
Executar JavaScript dentro de uma expressão de agregação pode diminuir o desempenho. Use somente o operador
$functionse os operadores de pipeline fornecidos não puderem atender às necessidades do seu aplicativo.
Sintaxe
O operador $function tem a seguinte sintaxe:
{ $function: { body: <code>, args: <array expression>, lang: "js" } }
Campo | Tipo | Descrição |
|---|---|---|
String ou código | A definição de função. Você pode especificar a definição da função como código ou string dos tipos de BSON. Consultetambém lang.
ou
| |
Array | Argumentos passados para o corpo da função . Se a função body não receber um argumento, você poderá especificar uma array Os elementos de array podem ser qualquer tipo BSON, incluindo Código. 2Consulte Exemplo: Alternativa | |
String | O idioma usado no corpo. Você deve especificar |
Considerações
Restrição de validação do esquema
Não é possível usar $function como parte de um predicado de consulta de validação de esquema.
Javascript Enablement
Para usar $function, você deve ter o script do lado do servidor habilitado (padrão).
Se você não usar $function (ou $accumulator, $where ou mapReduce), desative o script do lado do servidor:
Para uma instância
mongod, consulte opção de configuraçãosecurity.javascriptEnabledou opção de linha de comando--noscripting.Para instâncias do
mongos, consulte a opção de configuraçãosecurity.javascriptEnabledou a opção de linha de comando--noscripting.In earlier versions, MongoDB does not allow JavaScript execution onmongosinstances.
Consulte também ➤ Executar o MongoDB com opções de configuração seguras.
Alternativa para $where
O operador de query $where também pode ser utilizado para especificar a expressão JavaScript. No entanto:
O operador
$exprpermite o uso de expressões de agregação dentro do idioma da query.$functione$accumulatorpermitem que os usuários definam expressões de agregação personalizadas em JavaScript se os operadores de pipeline fornecidos não atenderem às necessidades do seu aplicativo.
Considerando os operadores de aggregation disponíveis:
O uso de
$exprcom operadores de agregação que não utilizam JavaScript (ou seja, operadores não$functione não$accumulator) é mais rápido do que$whereporque não executa JavaScript e deve ser preferido, se possível.No entanto, se você precisar criar expressões personalizadas,
$functioné preferível a$where.
Funções de array e string não suportadas
O MongoDB 6.0 atualiza o mecanismo JavaScript interno usado para expressões JavaScript do lado do servidor, $accumulator, $function e $where , bem como do MozJS-60 para o MozJS-91. Várias funções de array e string obsoletas e não padrão que existiam no MozJS-60 foram removidas no MozJS-91.
Exemplos
Exemplo 1: Exemplo de uso
Crie uma coleção de amostra denominada players com os seguintes 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 ] } ])
A seguinte operação de agregação utiliza o $addFields para adicionar novos campos a cada documento:
isFoundcujo valor é determinado pela expressão$functionpersonalizada que verifica se o hash MD5 do nome é igual a um hash especificado.messagecujo valor é determinado pela expressão$functionpersonalizada que formata uma mensagem de string utilizando um modelo.
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" } } } } ] )
A operação retorna os seguintes 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." }
Exemplo 2: Alternativa a $where
Observação
Alternativas de agregação preferidas acima de $where
O operador $expr permite o uso de expressões de agregação dentro do idioma da query. Além disso, o $function e o $accumulator permitem que os usuários definam expressões de agregação personalizadas em JavaScript se os operadores de pipeline fornecidos não atenderem às necessidades do seu aplicativo.
Considerando os operadores de aggregation disponíveis:
O uso de
$exprcom operadores de agregação que não utilizam JavaScript (ou seja, operadores não$functione não$accumulator) é mais rápido do que$whereporque não executa JavaScript e deve ser preferido, se possível.No entanto, se você precisar criar expressões personalizadas,
$functioné preferível a$where.
Como alternativa a uma query que usa o operador $where, você pode usar $expr e $function. Por exemplo, considere o exemplo $where a seguir.
db.players.find( { $where: function() { return (hex_md5(this.name) == "15b0a220baa16331e8d80e15367677ad") } } );
A operação db.collection.find() retorna o seguinte documento:
{ "_id" : 2, "name" : "Miss Ann Thrope", "scores" : [ 10, 10, 10 ] }
O exemplo pode ser expresso utilizando $expr e $function:
db.players.find( {$expr: { $function: { body: function(name) { return hex_md5(name) == "15b0a220baa16331e8d80e15367677ad"; }, args: [ "$name" ], lang: "js" } } } )