Descrição
Defina variáveis temporárias que podem ser referenciadas em etapas subsequentes do pipeline.
As variáveis criadas na etapa let(...) não são incluídas nos resultados finais
a menos que sejam explicitamente atribuídas a um campo em uma etapa posterior (por exemplo, usando
add_fields(...) ou
select(...)). Isso permite simplificar a lógica complexa
dividindo-a em componentes menores e reutilizáveis sem sobrecarregar os documentos de saída. A etapa let(...) é especialmente útil para subpipelines correlacionados, em que um subpipeline precisa referenciar um valor do escopo do documento pai.
Exemplos
Node.js
const results = await db.pipeline()
.collection("/awards")
// `let(...)` referred to as `define(...)` in the Web SDK.
.define(rand().as("r"))
.addFields(
switchOn(
lessThan(variable("r"), 0.05), constant("rare"),
lessThan(variable("r"), 0.25), constant("uncommon"),
constant("common")).as("random_score"))
.execute();
Comportamento
Variáveis x campos
Enquanto os campos representam dados armazenados em documentos, as variáveis são valores temporários que existem apenas durante a execução do pipeline.
| Campos | Variáveis | |
|---|---|---|
| Finalidade | acessar ou armazenar campos em documentos | gerar ou acessar valores temporários durante a execução do pipeline |
| Uso do SDK | field("name") |
variable("name") |
| Escopo | local para o documento atual | global para pipeline e subpipelines |
| Referências indefinidas | avalia como absent |
gera erro de execução |
Escopo :
Enquanto os campos são definidos no documento local, as variáveis são definidas em um
escopo separado e permanecem acessíveis em todas as etapas até a primeira ocorrência de
uma etapa que "mescla" vários documentos (como
aggregate(...) ou
distinct(...)). As etapas que "mesclam" vários
documentos não permitem que referências de variáveis sejam usadas depois, porque, ao mesclar
os resultados da etapa anterior, não há mais um valor para a
variável.
Faça: referencie uma variável depois de filtrar os campos do documento.
Node.js
const results = db.pipeline()
.collection("/awards")
.define(min(field("score").abs(), constant(100)).as("normalized_score"))
.select(field("__name__"), field("owner_id"))
// Successfully able to use the variable.
.where(variable("normalized_score").greaterThan(10))
.execute();
Não faça: referencie uma variável após uma agregação.
Node.js
const results = db.pipeline()
.collection("/awards")
.define(min(field("score").abs(), constant(100)).as("normalized_score"))
.aggregate({
accumulators: [ field("score").avg().as("avg_score") ],
groups: [ field("owner_id") ]
})
// Attempting to use the variable throws a request validation error.
.where(variable("normalized_score").greaterThan(10))
.execute();
Referências indefinidas :
Embora referenciar um campo indefinido seja bom (e apenas avalie como absent), tentar referenciar uma variável indefinida falhará durante a validação da solicitação. Nesse sentido, as referências de campo podem ser consideradas como a realização de uma pesquisa em um mapa no ambiente de execução, enquanto as referências de variáveis são mais parecidas com variáveis em uma linguagem de programação compilada estaticamente.
Escopo global e subconsultas
As variáveis são essenciais ao trabalhar com pipelines aninhados. Um subpipeline é executado no próprio escopo e só pode acessar os campos dos documentos que está processando. Para usar um valor do documento "pai" em uma subconsulta, primeiro defina-o como uma variável usando a etapa let(...).
Node.js
// Fetch reviewers alongside their negative reviews.
const pipeline = db.pipeline()
.collection("/reviewers")
// `let(...)` referred to as `define(...)` in the Web SDK.
.define(field("__name__").as("reviewer_name"))
.select("__name__", array(db.pipeline().collectionGroup("reviews")
.where(field("author").equals(variable("reviewer_name")))
.where(field("rating").lessThan(2))
.select("review", "rating")).as("negative_reviews"))
.execute();
Variáveis sobrepostas
Definir uma variável com um nome que já foi definido em uma etapa let(...) anterior vai substituir a variável anterior. Isso pode ser usado para atualizar o estado temporário à medida que o pipeline avança.
As variáveis referenciadas no subpipeline seguem regras de escopo léxico , como encontradas em muitas linguagens de programação, e se referem às variáveis com o mesmo nome definido pelo pipeline mais próximo (pai).
Comparação com add_fields(...)
A etapa let(...) se comporta de maneira semelhante à etapa
add_fields(...), mas, em vez de adicionar
campos ao documento, ela atribui valores a variáveis.