$function (agregação)
Nesta página
Definição
$function
Define uma função de agregação personalizada ou expressão em JavaScript.
Você pode usar o operador
$function
para definir funções personalizadas para implementar comportamentos não compatíveis com a linguagem de consulta do MongoDB. Veja também$accumulator
.Importante
Executar JavaScript dentro de uma expressão de agregação pode diminuir o desempenho. Use somente o operador
$function
se 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. Consulte também lang.
ou
| |
Array | Argumentos passados para o corpo da função. Se o corpo da função não receber um argumento, você poderá especificar uma array vazia Os elementos de array podem ser qualquer tipo BSON, incluindo Código. Consulte Exemplo 2: Alternativa para | |
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.javascriptEnabled
ou opção de linha de comando--noscripting
.Para instâncias do
mongos
, consulte a opção de configuraçãosecurity.javascriptEnabled
ou a opção de linha de comando--noscripting
.In earlier versions, MongoDB does not allow JavaScript execution onmongos
instances.
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
$expr
permite o uso de expressões de agregação dentro do idioma da query.$function
e$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
$expr
com operadores de agregação que não utilizam JavaScript (ou seja, operadores não$function
e não$accumulator
) é mais rápido do que$where
porque 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.
Para obter a lista completa das funções de array e string removidas, consulte as notas de compatibilidade da versão 6.0.
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:
isFound
cujo valor é determinado pela expressão$function
personalizada que verifica se o hash MD5 do nome é igual a um hash especificado.message
cujo valor é determinado pela expressão$function
personalizada 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
$expr
com operadores de agregação que não utilizam JavaScript (ou seja, operadores não$function
e não$accumulator
) é mais rápido do que$where
porque 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" } } } )