Menu Docs
Página inicial do Docs
/
Manual do banco de dados
/ / /

$ faceta ( operador de expressã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.

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

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.

À 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 mebibyte. Se exceder 16 mebibytes, a agregação produz um erro.

Dica

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.

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á um COLLSCAN. 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á um COLLSCAN 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.

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" : Decimal128("199.99"),
"tags" : [ "painting", "satire", "Expressionism", "caricature" ] }
{ "_id" : 2, "title" : "Melancholy III", "artist" : "Munch", "year" : 1902,
"price" : Decimal128("280.00"),
"tags" : [ "woodcut", "Expressionism" ] }
{ "_id" : 3, "title" : "Dancer", "artist" : "Miro", "year" : 1925,
"price" : Decimal128("76.04"),
"tags" : [ "oil", "Surrealism", "painting" ] }
{ "_id" : 4, "title" : "The Great Wave off Kanagawa", "artist" : "Hokusai",
"price" : Decimal128("167.30"),
"tags" : [ "woodblock", "ukiyo-e" ] }
{ "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931,
"price" : Decimal128("483.00"),
"tags" : [ "Surrealism", "painting", "oil" ] }
{ "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913,
"price" : Decimal128("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" : Decimal128("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 }
]
}

Os exemplos de C# nesta página utilizam o banco de dados sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver MongoDB .NET/C#.

A seguinte classe Movie modela os documentos na collection sample_mflix.movies:

public class Movie
{
public ObjectId Id { get; set; }
public int Runtime { get; set; }
public string Title { get; set; }
public string Rated { get; set; }
public List<string> Genres { get; set; }
public string Plot { get; set; }
public ImdbData Imdb { get; set; }
public int Year { get; set; }
public int Index { get; set; }
public string[] Comments { get; set; }
[BsonElement("lastupdated")]
public DateTime LastUpdated { get; set; }
}

Observação

ConventionPack para Pascal Case

As classes C# nesta página usam Pascal case para seus nomes de propriedade, mas os nomes de campo na coleção MongoDB usam Camel case. Para considerar essa diferença, você pode usar o seguinte código para registrar um ConventionPack quando o aplicativo iniciar:

var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

Para usar o driver MongoDB .NET/C# para adicionar um estágio $facet a um pipeline de agregação, chame o método Facet() em um objeto PipelineDefinition.

O exemplo a seguir cria um estágio de pipeline que executa duas agregações paralelas. A primeira agregação distribui documentos recebidos em cinco grupos pelo valor de seu campo Runtime. A segunda agregação conta cada valor no campo Rated e retorna a contagem para cada valor, limitada aos cinco principais valores.

var bucketPipeline = new EmptyPipelineDefinition<Movie>()
.BucketAuto(
groupBy: m => m.Runtime,
buckets: 5);
var bucketFacet = AggregateFacet.Create(
name: "Runtimes",
pipeline: bucketPipeline);
var countLimitPipeline = new EmptyPipelineDefinition<Movie>()
.SortByCount(m => m.Rated)
.Limit(5);
var countFacet = AggregateFacet.Create(
"Ratings", countLimitPipeline);
var pipeline = new EmptyPipelineDefinition<Movie>()
.Facet(bucketFacet, countFacet);

Os exemplos do Node.js nesta página utilizam o sample_mflix banco de dados do a partir dos conjuntos de dados de amostra do Atlas . Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver do MongoDB Node.js

Para usar o driver Node.js do MongoDB para adicionar um estágio $facet a um pipeline de agregação , use o operador $facet em um objeto de pipeline.

O exemplo a seguir cria um estágio de pipeline que executa duas agregações paralelas. A primeira agregação distribui documentos recebidos em cinco grupos pelo valor de seu runtime campo usando o estágio. A segunda agregação conta cada valor $bucketAuto no rated campo e retorna a contagem dos cinco principais valores usando os estágios e. Em seguida, o exemplo $sortByCount $limit executa o agregação pipeline:

const pipeline = [
{
$facet: {
bucketPipeline: [
{
$bucketAuto: {
groupBy: "$runtime",
buckets: 5
}
}
],
countLimit: [
{ $sortByCount: "$rated" },
{ $limit: 5 }
]
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

Para saber mais sobre os estágios de pipeline relacionados, consulte os $bucketAuto $sortByCountguias $limit , e .

Voltar

$documentos

Nesta página