Database
[{"fields":{"contract_first":[],"contract_second":[{"position":"Bob"}]},"_id":1},{"fields":{"contract_first":[{"position":"Anna"}],"contract_second":[]},"_id":2},{"fields":{"contract_first":[{"position":"Bob"}],"contract_second":[]},"_id":3},{"fields":{"contract_first":[{"position":"Ellen"}],"contract_second":[{"position":"Dave"}]},"_id":4},{"fields":{"contract_first":[{"position":"Ellen"}],"contract_second":[{"position":"Charlie"}]},"_id":5},{"fields":{"contract_first":[],"contract_second":[{"position":"Charlie"}]},"_id":6},{"fields":{"contract_first":[],"contract_second":[{"position":"Dave"}]},"_id":7},{"fields":{"contract_first":[{"position":"Dave"}],"contract_second":[{"position":"Charlie"}]},"_id":8},{"fields":{"contract_first":[{"position":"Dave"}],"contract_second":[{"position":"Ellen"}]},"_id":9}]
Query
db.collection.aggregate([{$set:{/** add both the position-names to an array* but don't sort here*/names:{$concatArrays:["$fields.contract_first.position","$fields.contract_second.position"]}}},{/** convert to lowercase, skip if not needed* can be combined with the set above*/$set:{names:{$map:{input:"$names",as:"name",in:{$toLower:"$$name"}}}}},{/** use each name as the sort key* using alphabetical order and then record order*/$set:{sort_key1:{$min:"$names"},sort_key2:{$max:"$names"},sort_key3:{$first:"$names"},sort_key4:{$last:"$names"}}},{/** use each of the keys to sort & _id if necessary*/$sort:{sort_key1:1,sort_key2:1,sort_key3:1,sort_key4:1,_id:1}},{/** comment this out to see the sort_keys*/$unset:["names","sort_key1","sort_key2","sort_key3","sort_key4"]}])