sql >> Databáze >  >> NoSQL >> MongoDB

Použití dynamické hodnoty v agregaci

Obecným požadavkem zde je zahrnout rozsah pro "month" hodnoty v úvahu, kde je "větší než" -5 měsíce "před" a "méně než" +2 měsíce "po", jak je zaznamenáno v "enrolled" položky pole.

Problém je v tom, že tyto hodnoty jsou založeny na "dateJoined" , je třeba je upravit o správný interval mezi "dateJoined" a "dateActivated" . Díky tomu je výraz efektivně:

monthsDiff = (yearActivated - yearJoined)*12 + (monthActivated - monthJoined)

where month >= ( startRange + monthsDiff ) and month <= ( endRange + monthsDiff )
and enrolled = "01"

Nebo logicky vyjádřené "Měsíce mezi vyjádřeným rozsahem upravené o rozdíl počtu měsíců mezi připojením a aktivací" .

Jak je uvedeno v komentáři, úplně první věc, kterou zde musíte udělat, je uložit tyto hodnoty data jako BSON Date na rozdíl od jejich současných zdánlivých „řetězcových“ hodnot. Jakmile to uděláte, můžete použít následující agregaci k výpočtu rozdílu od dodaných dat a před počítáním odpovídajícím způsobem filtrovat upravený rozsah z pole:

var rangeStart = -5,
    rangeEnd = 2;

db.getCollection('enrollments').aggregate([
  { "$project": {
    "enrollments": {
      "$size": {
        "$filter": {
          "input": "$enrolled",
          "as": "e",
          "cond": {
            "$let": {
              "vars": {
                "monthsDiff": {
                  "$add": [
                    { "$multiply": [
                      { "$subtract": [
                        { "$year": "$dateActivated" },
                        { "$year": "$dateJoined" }
                      ]},
                      12
                    }},
                    { "$subtract": [
                      { "$month": "$dateActivated" },
                      { "$month": "$dateJoined" }
                    ]}
                  ]
                }
              },
              "in": {
                "$and": [
                  { "$gte": [ { "$add": [ rangeStart, "$$monthsDiff" ] }, "$$e.month" ] },
                  { "$lte": [ { "$add": [ rangeEnd, "$$monthsDiff" ] }, "$$e.month" ] },
                  { "$eq": [ "$$e.enrolled", "01" ] }
                ]
              }
            }
          } 
        }
      }
    }
  }}
])

Platí to tedy stejné $filter na pole, o které jste se pokoušeli, ale nyní bere v úvahu i upravené hodnoty v rozsahu měsíců, podle kterých se má filtrovat.

Abychom vám usnadnili čtení, použijeme $let což umožňuje výpočet společné hodnoty získané pro $$monthsDiff jak je implementováno v proměnné. Zde je použit původně vysvětlený výraz pomocí $year a $month extrahovat tyto číselné hodnoty z uložených dat.

Použití dalších matematických operátorů $add , $subtract a $multiply můžete vypočítat rozdíl v měsících a také později použít k úpravě hodnot "rozsahu" v logických podmínkách pomocí $gte a $lte .

Konečně, protože $filter vydává pole pouze záznamů vyhovujících podmínkám, abychom "počítali" použijeme $size která vrací délku "filtrovaného" pole, což je "počet" shod.

V závislosti na zamýšleném účelu může být celý výraz poskytnut také jako argument pro $sum jako $group akumulátor, pokud to byl skutečně záměr.



  1. Získejte sbírku a přidejte k odpovědi hodnotu

  2. Doporučený způsob odstranění objektu v MongoDB na základě trasy

  3. Jak vytvořit službu CUPS pro mongoDB?

  4. připojení k mongoDB