Partager via


$expr

L’opérateur $expr permet l’utilisation d’expressions d’agrégation dans le langage de requête, ce qui nous permet de comparer des champs du même document, d’effectuer des calculs et d’utiliser des opérateurs d’agrégation dans les opérations de recherche. L’opérateur $expr est utile pour les comparaisons de champs complexes qui ne peuvent pas être effectuées avec les opérateurs de requête traditionnels.

Syntaxe

{
  $expr: { <aggregation expression> }
}

Paramètres

Paramètre Descriptif
<aggregation expression> Toute expression d’agrégation valide qui prend la valeur booléenne. L’expression inclut des comparaisons de champs, des opérations arithmétiques, des expressions conditionnelles et d’autres opérateurs d’agrégation.

Examples

Considérez cet exemple de document de la collection des magasins.

{
    "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4",
    "name": "First Up Consultants | Beverage Shop - Satterfieldmouth",
    "location": {
        "lat": -89.2384,
        "lon": -46.4012
    },
    "staff": {
        "totalStaff": {
            "fullTime": 8,
            "partTime": 20
        }
    },
    "sales": {
        "totalSales": 75670,
        "salesByCategory": [
            {
                "categoryName": "Wine Accessories",
                "totalSales": 34440
            },
            {
                "categoryName": "Bitters",
                "totalSales": 39496
            },
            {
                "categoryName": "Rum",
                "totalSales": 1734
            }
        ]
    },
    "promotionEvents": [
        {
            "eventName": "Unbeatable Bargain Bash",
            "promotionalDates": {
                "startDate": {
                    "Year": 2024,
                    "Month": 6,
                    "Day": 23
                },
                "endDate": {
                    "Year": 2024,
                    "Month": 7,
                    "Day": 2
                }
            },
            "discounts": [
                {
                    "categoryName": "Whiskey",
                    "discountPercentage": 7
                },
                {
                    "categoryName": "Bitters",
                    "discountPercentage": 15
                },
                {
                    "categoryName": "Brandy",
                    "discountPercentage": 8
                },
                {
                    "categoryName": "Sports Drinks",
                    "discountPercentage": 22
                },
                {
                    "categoryName": "Vodka",
                    "discountPercentage": 19
                }
            ]
        },
        {
            "eventName": "Steal of a Deal Days",
            "promotionalDates": {
                "startDate": {
                    "Year": 2024,
                    "Month": 9,
                    "Day": 21
                },
                "endDate": {
                    "Year": 2024,
                    "Month": 9,
                    "Day": 29
                }
            },
            "discounts": [
                {
                    "categoryName": "Organic Wine",
                    "discountPercentage": 19
                },
                {
                    "categoryName": "White Wine",
                    "discountPercentage": 20
                },
                {
                    "categoryName": "Sparkling Wine",
                    "discountPercentage": 19
                },
                {
                    "categoryName": "Whiskey",
                    "discountPercentage": 17
                },
                {
                    "categoryName": "Vodka",
                    "discountPercentage": 23
                }
            ]
        }
    ]
}

Exemple 1 : Comparer le personnel à temps plein et à temps partiel

L’exemple récupère les magasins avec le nombre d’employés à temps partiel supérieurs à ceux à temps plein.

db.stores.find({_id: "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
  $expr: {
    $gt: ["$staff.employeeCount.partTime", "$staff.employeeCount.fullTime"]
  }
})

La requête compare deux champs dans le document spécifié (_id) et le retourne uniquement si la condition est remplie (le nombre d’employés à temps plein dépasse le nombre d’employés à temps partiel).

{
  "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
  "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury",
  "location": {
    "lat": 70.1272,
    "lon": 69.7296
  },
  "staff": {
      "contractorCount": 5,
      "employeeCount": { "fullTime": 19, "partTime": 20 }
    },
  "sales": {
    "totalSales": 151864,
    "salesByCategory": [
      {
        "categoryName": "Sound Bars",
        "totalSales": 2120
      },
      {
        "categoryName": "Home Theater Projectors",
        "totalSales": 45004
      }
    },
    "storeOpeningDate": ISODate("2024-09-23T13:45:01.480Z"),
    "lastUpdated": ISODate("2025-06-11T11:06:57.922Z"),
    "status": "active",
    "category": "high-volume",
    "priority": 1,
    "reviewDate": ISODate("2025-06-11T11:10:50.276Z")
  }
]

Exemple 2 : Logique conditionnelle avec emplacement du magasin

L’exemple illustre l’utilisation de logique conditionnelle avec $expr des magasins de tirage dans l’hémisphère sud où le ratio d’efficacité du personnel (ventes par employé) dépasse 2000.

db.stores.find({_id: "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
  $expr: {
    $and: [
      { $gte: ["$location.lat", 70.1272] },
      {
        $gt: [
          {
            $divide: [
              "$sales.totalSales",
              { $add: ["$staff.employeeCount.fullTime", "$staff.employeeCount.partTime"] }
            ]
          },
          2000
        ]
      }
    ]
  }
}).limit(1)

Cette requête retourne le résultat suivant.

[
  {
    "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74",
    "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury",
    "location": {
      "lat": 70.1272,
      "lon": 69.7296
    },
    "staff": {
      "totalStaff": {
        "fullTime": 19,
        "partTime": 20
      }
    },
    "sales": {
      "totalSales": 151864,
      "salesByCategory": [
        {
          "categoryName": "Sound Bars",
          "totalSales": 2120
        },
        {
          "categoryName": "Home Theater Projectors",
          "totalSales": 45004
        }
      ]
    },
    "storeOpeningDate": ISODate("2024-09-23T13:45:01.480Z"),
    "lastUpdated": ISODate("2025-06-11T11:06:57.922Z"),
    "status": "active",
    "category": "high-volume",
    "priority": 1,
    "reviewDate": ISODate("2025-06-11T11:10:50.276Z")
  }
]