Why aggregate operators behave differently than projection operators?

I have BSON data which I want to filter based on discount field. The JSON entry might have missing discount field or might have null value. I want to filter “discount > 10 or discount < 10” (which is ultimately discount !=10).

[
  {
    "id": 1,
    "discount": 10
  },
  {
    "id": 2
  },
  {
    "id": 3,
    "discount": null
  },
  {
    "id": 4,
    "discount": 20
  }
]

Using projection operators: Mongo playground

Filter Applied:

db.collection.find({
  "$or": [
    {
      "discount": {
        "$lt": 10
      }
    },
    {
      "discount": {
        "$gt": 10
      }
    }
  ]
})

Output:

[
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "discount": 20,
    "id": 4
  }
]

Using aggregate operators:

Filter applied: Mongo playground

db.collection.find({
  "$expr": {
    "$or": [
      {
        "$lt": [
          "$discount",
          10
        ]
      },
      {
        "$gt": [
          "$discount",
          10
        ]
      }
    ]
  }
})

Output:

[
  {
    "_id": ObjectId("5a934e000102030405000001"),
    "id": 2
  },
  {
    "_id": ObjectId("5a934e000102030405000002"),
    "discount": null,
    "id": 3
  },
  {
    "_id": ObjectId("5a934e000102030405000003"),
    "discount": 20,
    "id": 4
  }
]

Why the output differs here? In case of using aggregation operator, I am getting those JSON entries as well whose discount field is undefined or null.

I know we can add $and condition excluding the undefined and null json (Mongo playground). but is there any other way?

How to mimic the filter condition with aggregate operators to get the same output as of projection operators?