Menu Docs

Página inicial do DocsDesenvolver aplicaçõesManual do MongoDB

$function (agregação)

Nesta página

  • Definição
  • Sintaxe
  • Considerações
  • Exemplos
$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 suportados pela 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 o operador $function somente se os operadores de pipeline fornecidos não puderem atender às necessidades do seu aplicativo.

O operador $function tem a seguinte sintaxe:

{
$function: {
body: <code>,
args: <array expression>,
lang: "js"
}
}
Campo
Tipo
Descrição
corpo, corpo
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.

function(arg1, arg2, ...) { ... }

ou

"function(arg1, arg2, ...) { ... }"

Array

Argumentos passados para o corpo da função . Se a função body 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 $where.

String

O idioma usado no corpo. Você deve especificar lang: "js".

Você não pode utilizar o $function como parte da validação do esquema expressão da consulta.

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), desabilite os scripts do lado do servidor:

Consulte também ➤ Executar o MongoDB com opções de configuração seguras.

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 do $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 customizadas, prefere-se { $function a $where.

MongoDB 6.0 atualiza o mecanismo JavaScript interno utilizado para o JavaScript do lado do servidor, expressões $accumulator, $function e $where , e do MozJS-60 para o MozJS-91. Várias funções de array e string de caracteres não padrão obsoletas que existiam no MozJS-60 são 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.

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." }

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 consulta. E $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 do $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 customizadas, prefere-se { $function 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"
} } } )
← $floor (agregação)