Ce face $expr
Filtrele obișnuite compară un câmp cu o valoare fixă. $expr (MongoDB 3.6+) acceptă expresii de agregare, în care '$stoc' înseamnă valoarea câmpului stoc. Astfel poți compara două câmpuri între ele sau poți filtra după un calcul (lungimea unui tablou, o sumă, o dată).
Operatorii de comparare din $expr au forma de agregare, cu un tablou de două valori: { $lt: ['$stoc', '$stocMinim'] }. Același operator se folosește și în $match sau în $lookup cu pipeline.
Parametri
| Parametru | Descriere |
|---|---|
expresie |
Orice expresie de agregare care întoarce adevărat sau fals. |
Ce returnează
Un cursor cu documentele pentru care expresia este adevărată.
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: [] }
])
db.produse.insertMany([
{ _id: 'caiet', stoc: 40, stocMinim: 50 },
{ _id: 'pix', stoc: 120, stocMinim: 30 },
{ _id: 'rucsac', stoc: 5, stocMinim: 5 }
])
Exemplul 1: Produse sub stocul minim
Se compară două câmpuri ale aceluiași document; rucsacul are stocul egal cu minimul, deci nu apare.
db.produse.find({ $expr: { $lt: ['$stoc', '$stocMinim'] } })
Ieșire în mongosh
[ { _id: 'caiet', stoc: 40, stocMinim: 50 } ]
Exemplul 2: Comenzi cu cel puțin două produse
Operatorul de agregare $size calculează lungimea tabloului.
db.comenzi.find({ $expr: { $gte: [{ $size: '$produse' }, 2] } }, { client: 1 })
Ieșire în mongosh
[ { _id: 1, client: 'Ana' }, { _id: 3, client: 'Ioana' } ]
Greșeli frecvente
- Fără
$în față,'stoc'este textul „stoc”, nu valoarea câmpului. - În
$expr, operatorul de agregare$sizedă eroare dacă un document nu are tabloul; protejează-te cu{ $ifNull: ['$produse', []] }. $exprpoate folosi indexuri doar pentru comparații simple de egalitate și interval cu valori fixe; comparațiile între câmpuri scanează documentele.
Comenzi înrudite
$match: Etapa $match păstrează în pipeline doar documentele care se potrivesc filtrului, cu aceeași sintaxă ca find().$size: Operatorul $size găsește documentele în care un tablou are exact numărul dat de elemente.$addFields / $set: Etapa $addFields (alias $set) adaugă câmpuri calculate sau suprascrie câmpuri existente, păstrând restul documentului.