Trouble with aggregation expressions to extract arrays from non-array fields

i have some objects with a field which, for space reasons, uses three possible encodings:

  1. field is missing (0 values)
{
}
  1. field is a scalar (1 value)
{
    the_field: ObjectIdentifier(...)
}
  1. field is an array (>=2 values)
{
    the_field: [ObjectIdentifier(...), ObjectIdentifier(...), ... ]
}

i have documents that contain arrays of this object:

{
    _id: ...
    r: [
        { },
        { the_field: ObjectIdentifier(...) },
        { the_field: [ObjectIdentifier(...), ObjectIdentifier(...), ... ] },
        ...
    ]
}

now i need to perform a $lookup using the ObjectIdentifiers stored in each element of $r, but i am struggling to come up with an aggregation expression that can flatten these objects into an array of ObjectIdentifiers. what is the best way to accomplish this?

for context, case #2 does not currently exist in our database, only case #1 and #3 exist, so we are currently using:

{ $ifNull: [ $$self.the_field, [] ] }

inside a $reduce.

but i had a hard time generalizing this to cover case #2. since it does not currently exist, we could use a different name for the field if that would help.

I think a simple extension of your current logic but using $switch should work to unify the_field to an array. Check this playground.

I did the playground as if the_field was at the top level which is what you will get after the $unwind of the field r.

After the $set stage the_field will be unified to an array, then you could $unwind and $lookup.