$project în MongoDB & NoSQL

Agregare & Analytics MongoDB 2.2

Etapa $project alege, redenumește sau calculează câmpurile documentelor care merg mai departe în pipeline.

Sintaxă
{ $project: { <camp>: 1 | 0 | <expresie>, ... } }

Ce face $project

$project funcționează ca proiecția din find() (1 = include, 0 = exclude), dar poate și calcula câmpuri noi cu expresii: { nrProduse: { $size: '$produse' } }, { totalCuTVA: { $multiply: ['$total', 1.21] } }. Un câmp nou se poate numi oricum, inclusiv cu notația cu punct pentru subdocumente.

Când vrei doar să adaugi câmpuri și să le păstrezi pe toate celelalte, $addFields (sau $set) e mai simplu. Pentru a elimina câteva câmpuri, există și etapa $unset (MongoDB 4.2+).

Parametri

Parametru Descriere
camp: 1 / 0 Include / exclude câmpul.
camp: expresie Câmp calculat sau redenumit ('$alt_camp').

Ce returnează

Documentele cu forma nouă.

Exemple

Exemplele de pe această pagină pornesc de la datele de mai jos. Rulează mai întâi acest cod, apoi exemplul.

use magazin
db.comenzi.insertMany([
  { _id: 1, client: 'Ana', oras: 'Iași', total: 120, status: 'livrata', produse: ['caiet', 'pix'] },
  { _id: 2, client: 'Dan', oras: 'Cluj', total: 85, status: 'noua', produse: ['carte'] },
  { _id: 3, client: 'Ioana', oras: 'Iași', total: 240, status: 'livrata', produse: ['rucsac', 'caiet', 'pix'] },
  { _id: 4, client: 'Mihai', oras: 'Brașov', total: 60, status: 'anulata', produse: [] }
])

Exemplul 1: Total cu TVA și număr de produse

$round rotunjește la două zecimale.

db.comenzi.aggregate([
  { $match: { status: 'livrata' } },
  { $project: { _id: 0, client: 1, totalCuTVA: { $round: [{ $multiply: ['$total', 1.21] }, 2] }, nrProduse: { $size: '$produse' } } }
])

Ieșire în mongosh

[
  { client: 'Ana', totalCuTVA: 145.2, nrProduse: 2 },
  { client: 'Ioana', totalCuTVA: 290.4, nrProduse: 3 }
]

Exemplul 2: Redenumire și subdocument nou

Orașul trece în locatie.oras, iar suma este un alt nume pentru total.

db.comenzi.aggregate([{ $match: { _id: 2 } }, { $project: { client: 1, suma: '$total', 'locatie.oras': '$oras' } }])

Ieșire în mongosh

[ { _id: 2, client: 'Dan', suma: 85, locatie: { oras: 'Cluj' } } ]

Greșeli frecvente

  • Ca la find(), nu poți amesteca includeri și excluderi (cu excepția _id: 0).
  • Un câmp calculat cu valoarea 1 literal se scrie { $literal: 1 }; simplul 1 înseamnă „include câmpul”.

Comenzi înrudite

  • $addFields / $set: Etapa $addFields (alias $set) adaugă câmpuri calculate sau suprascrie câmpuri existente, păstrând restul documentului.
  • find() cu proiecție: Al doilea argument al lui find() alege ce câmpuri întoarce interogarea: 1 = include, 0 = exclude.
  • $group: Etapa $group grupează documentele după o cheie și calculează totaluri: $sum, $avg, $min, $max, $push, $addToSet.