Menu Docs
Página inicial do Docs
/
Manual 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 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.

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.

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

ou

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

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 $where.

String

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

Não é possível usar $function como parte de um predicado de consulta de validação de esquema.

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:

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

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.

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

Voltar

$floor