db.c.insertOne({e:'2025-04-01'});
db.c.aggregate([{$match: { e: {"$lte": "2025-06-24"}}}]) // one match
db.c.aggregate([{ "$addFields": { "today": "2025-06-24"}},{$match: { e: {"$lte": "$today"}}}]) // no match
db.c.aggregate([{ "$addFields": { "today": "2025-06-24"}},{$match: { $expr: {"$lte":[ "$e", "$today"]}}}]) // one match
// instead of $lte when using $gte
db.c.aggregate([{$match: { e: {"$gte": "2025-01-01"}}}]) // one match
db.c.aggregate([{ "$addFields": { "first": "2025-01-01"}},{$match: { e: {"$gte": "$first"}}}]) // one match
Should $lte work as $gte does?
«The $lte compares both value and type, using the specified BSON comparison order for values of different types.»
You are not comparing the value of the field e with the value of the fields today or first, despite using $. You are comparing the value of the field e with the strings $today and $first.
This is different when using $expr. This is why you get different results in
It just happens that “2025-01-01” is indeed greater than the string $first.