Ian McInnes
Ian McInnes

Reputation: 29

How to query data if date is certain range before today's date?

I'm writing a MERN stack app to keep track of product's expiry dates in a store. The app will check to see if today's date is the same or after the product's "expiry date".

The query I wrote to find this works. However, certain products also get reduced if the expiry date is three days after today's date.

Here is the sample data:


[
  {
    "section": "coke",
    "dateLastChecked": ISODate("2025-01-01"),
    "products": [
      {
        _id: 1,
        name: "Coke 500ml",
        expiryDate: ISODate("2025-01-01")
      },
      {
        _id: 2,
        name: "Diet Coke 500ml",
        expiryDate: ISODate("2025-02-02")
      }
    ]
  },
  {
    "section": "pepsi",
    "dateLastChecked": ISODate("2025-01-01"),
    "products": [
      {
        _id: 3,
        name: "Pepsi 500ml",
        expiryDate: ISODate("2025-01-16")
      },
      {
        _id: 4,
        name: "Diet Pepsi 500ml",
        expiryDate: ISODate("2025-01-19")
      }
    ]
  }
]

And here is the query I used to check it against today's date (this works)


db.collection.aggregate([
  {
    "$unwind": "$products"
  },
  {
    "$match": {
      "products.expiryDate": {
        $lte: new Date()
      }
    }
  },
  {
    "$addFields": {
      "products.section": "$section"
    }
  },
  {
    "$replaceRoot": {
      "newRoot": "$products"
    }
  }
])

But when I try to modify the query for "three days before it expires" it does not. I tried "dateSubtract" to subtract three days from the "new Date" object, but nothing gets returned, even though no error is given.


db.collection.aggregate([
  {
    "$unwind": "$products"
  },
  {
    "$match": {
      "products.expiryDate": {
        $lte: {
          $dateSubtract: {
            startDate: new Date(),
            unit: "day",
            amount: 3
          }
        }
      }
    }
  },
  {
    "$addFields": {
      "products.section": "$section"
    }
  },
  {
    "$replaceRoot": {
      "newRoot": "$products"
    }
  }
])

How should I reword this?

Upvotes: 1

Views: 59

Answers (1)

aneroid
aneroid

Reputation: 15987

To do that kind of comparison - a field with an expression, you need to use a $expr with $lte:

db.collection.aggregate([
  {
    "$unwind": "$products"
  },
  {
    "$match": {
      $expr: {
        $lte: [
          "$products.expiryDate",
          {
            $dateSubtract: {
              startDate: new Date(),
              unit: "day",
              amount: 3
            }
          }
        ]
      }
    }
  },
  {
    "$addFields": {
      "products.section": "$section"
    }
  },
  {
    "$replaceRoot": {
      "newRoot": "$products"
    }
  }
])

Mongo Playground

Upvotes: 2

Related Questions