$facet (agregação)
Definição
$facet
Processa vários pipelines de agregação em um único estágio no mesmo conjunto de documentos de entrada. Cada subpipeline tem seu próprio campo no documento de saída, onde seus resultados são armazenados como uma array de documentos.
O estágio
$facet
permite criar agregações multifacetadas que caracterizam dados em várias dimensões, ou facets, dentro de um único estágio de agregação. As agregações multifacetadas fornecem vários filtros e categorizações para orientar a navegação e a análise de dados. Os varejistas geralmente usam faceting para restringir os resultados da procurar, criando filtros sobre o preço do produto, fabricante, tamanho etc.Os documentos de entrada são passados para o estágio
$facet
apenas uma vez.$facet
permite várias agregações no mesmo definir de documentos de entrada, sem a necessidade de recuperar os documentos de entrada várias vezes.
Compatibilidade
Você pode utilizar o $facet
para implantações hospedadas nos seguintes ambientes:
MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Sintaxe
O estágio $facet
tem a seguinte forma:
{ $facet: { <outputField1>: [ <stage1>, <stage2>, ... ], <outputField2>: [ <stage1>, <stage2>, ... ], ... } }
Especifique o nome do campo de saída para cada pipeline especificado.
Considerações
À medida que cada estágio de um $facet
é executado, o documento resultante é limitado a 100 megabytes. Observe que o sinalizador allowDiskUse não afeta o limite de tamanho de 100 megabytes, uma vez que $facet
não pode ser transferido para o disco.
O documento de saída final está sujeito ao limite de tamanho do documento BSON de 16 megabytes. Se exceder 16 megabytes, a agregação produz um erro.
Comportamento
Os estágios de agregação relacionados a facetas grupo e agrupam os documentos recebidos. Especifique qualquer um dos seguintes estágios relacionados a facet em diferentes $facet
subpipelines <stage>
para realizar uma agregação multifacetada:
Outros estágios de agregação também podem ser utilizados com $facet
com as seguintes exceções:
Cada subpipeline em $facet
recebe exatamente o mesmo definir de documentos de entrada. Esses subpipelines são totalmente independentes uns dos outros e a array de documentos gerada por cada um deles é armazenada em campos separados no documento de saída. A saída de um subpipeline não pode ser usada como entrada para um subpipeline diferente dentro do mesmo estágio $facet
. Se forem necessárias outras agregações, adicione estágios adicionais após $facet
e especifique o nome do campo, <outputField>
, da saída do subpipeline desejado.
Uso do índice
A ordem do pipeline determina como o estágio $facet
usa índices.
Se o estágio
$facet
for o primeiro estágio de um pipeline, o estágio executará umCOLLSCAN
. O estágio$facet
não usa índices se for o primeiro estágio no pipeline.Se o estágio
$facet
chegar mais tarde no pipeline e os estágios anteriores tiverem usado índices,$facet
não acionará umCOLLSCAN
durante a execução.
Por exemplo, os estágios $match
ou $sort
que vêm antes de um estágio $facet
podem usar índices e o $facet
não aciona um COLLSCAN
.
Para sugestões de otimização, consulte: Otimização do aggregation pipeline.
Exemplo
Considere uma loja online cujo estoque esteja armazenado na seguinte coleção artwork
:
{ "_id" : 1, "title" : "The Pillars of Society", "artist" : "Grosz", "year" : 1926, "price" : NumberDecimal("199.99"), "tags" : [ "painting", "satire", "Expressionism", "caricature" ] } { "_id" : 2, "title" : "Melancholy III", "artist" : "Munch", "year" : 1902, "price" : NumberDecimal("280.00"), "tags" : [ "woodcut", "Expressionism" ] } { "_id" : 3, "title" : "Dancer", "artist" : "Miro", "year" : 1925, "price" : NumberDecimal("76.04"), "tags" : [ "oil", "Surrealism", "painting" ] } { "_id" : 4, "title" : "The Great Wave off Kanagawa", "artist" : "Hokusai", "price" : NumberDecimal("167.30"), "tags" : [ "woodblock", "ukiyo-e" ] } { "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931, "price" : NumberDecimal("483.00"), "tags" : [ "Surrealism", "painting", "oil" ] } { "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913, "price" : NumberDecimal("385.00"), "tags" : [ "oil", "painting", "abstract" ] } { "_id" : 7, "title" : "The Scream", "artist" : "Munch", "year" : 1893, "tags" : [ "Expressionism", "painting", "oil" ] } { "_id" : 8, "title" : "Blue Flower", "artist" : "O'Keefe", "year" : 1918, "price" : NumberDecimal("118.42"), "tags" : [ "abstract", "painting" ] }
A operação a seguir usa os facets do MongoDB para fornecer aos clientes o estoque da loja categorizado em várias dimensões, como tags, preço e ano criado. Esse estágio $facet
tem três subpipelines que usam $sortByCount
, $bucket
ou $bucketAuto
para realizar essa agregação de facet multifacetada. Os documentos de entrada do artwork
são obtidos a partir do banco de dados somente uma vez, no início da operação:
db.artwork.aggregate( [ { $facet: { "categorizedByTags": [ { $unwind: "$tags" }, { $sortByCount: "$tags" } ], "categorizedByPrice": [ // Filter out documents without a price e.g., _id: 7 { $match: { price: { $exists: 1 } } }, { $bucket: { groupBy: "$price", boundaries: [ 0, 150, 200, 300, 400 ], default: "Other", output: { "count": { $sum: 1 }, "titles": { $push: "$title" } } } } ], "categorizedByYears(Auto)": [ { $bucketAuto: { groupBy: "$year", buckets: 4 } } ] } } ])
A operação retorna o seguinte documento:
{ "categorizedByYears(Auto)" : [ // First bucket includes the document without a year, e.g., _id: 4 { "_id" : { "min" : null, "max" : 1902 }, "count" : 2 }, { "_id" : { "min" : 1902, "max" : 1918 }, "count" : 2 }, { "_id" : { "min" : 1918, "max" : 1926 }, "count" : 2 }, { "_id" : { "min" : 1926, "max" : 1931 }, "count" : 2 } ], "categorizedByPrice" : [ { "_id" : 0, "count" : 2, "titles" : [ "Dancer", "Blue Flower" ] }, { "_id" : 150, "count" : 2, "titles" : [ "The Pillars of Society", "The Great Wave off Kanagawa" ] }, { "_id" : 200, "count" : 1, "titles" : [ "Melancholy III" ] }, { "_id" : 300, "count" : 1, "titles" : [ "Composition VII" ] }, { // Includes document price outside of bucket boundaries, e.g., _id: 5 "_id" : "Other", "count" : 1, "titles" : [ "The Persistence of Memory" ] } ], "categorizedByTags" : [ { "_id" : "painting", "count" : 6 }, { "_id" : "oil", "count" : 4 }, { "_id" : "Expressionism", "count" : 3 }, { "_id" : "Surrealism", "count" : 2 }, { "_id" : "abstract", "count" : 2 }, { "_id" : "woodblock", "count" : 1 }, { "_id" : "woodcut", "count" : 1 }, { "_id" : "ukiyo-e", "count" : 1 }, { "_id" : "satire", "count" : 1 }, { "_id" : "caricature", "count" : 1 } ] }