Q:

MongoDB sort on field in nested document with missing values

Input sample data
/* 1 */
{  "name" : "alice",
    "attibutes" : [ 
        { "key" : "marks", "value" : 10 }, 
        { "key" : "age", "value" : 10 }
    ]
}

/* 2 */
{  "name" : "bob",
   "attibutes" : [   {  "key" : "marks", "value" : 20 } ]
}

/* 3 */
{ "name" : "charlie",
  "attibutes" : [  { "key" : "age", "value" : 20 } ]
}

/* 4 */
{ "name" : "dan",
  "attibutes" : []
}

/* 5 */
{ "name" : "el",
  "attibutes" : [ 
        { "key" : "marks", "value" : 5}, 
        { "key" : "age", "value" : 5}
    ]
}

My use case is I need to filter the documents on marks and sort on age. Not all my documents have the necessary data.
I expect the documents not having marks not present in the output, but expect even though a document does not have value for age the document appear in the output.
Query 1: just filter on marks, works as expected, returns two documents
db.getCollection('students').aggregate([
{
  $match: {
    attributes: { 
      $elemMatch: {
        value: {$gte:10},
        key:"marks"
      }
    }
    }
  }
]) 

returns documents corresponding to Alice and Bob. EXPECTED
now adding sorting, which I am doing by unwinding, the query looks like
db.getCollection('students').aggregate([  
  {  
    $match:{  
      attributes:{  
        $elemMatch:{  
          value:{  
            $gte:10
          },
          key:"marks"
        }
      }
    }
  },
  {  $addFields:{ attributes_unwind:"$attributes" } },
  {  $unwind:"$attributes_unwind" }, //UNWIND OPERATION
  {  $match:{  "attributes_unwind.key":"age" } },
  {  $sort:{  "attributes_unwind.value":1 } },
  {  $project:{    "attributes_unwind":false } }
])

this query because of the unwind + match + sort removes the document corresponding to bob which does not have an entry for age.
I want to bypass this problem by adding a key value for age (sort attribute) before the line marked //UNWIND OPERATION. This insertion should be conditional only when the original list does not have a key for age. 
What I have so far is 
db.getCollection('students').aggregate([
{
    $match: {
attributes: { 
                    $elemMatch: {
                        value: {$gte:10},
                        key:"marks"
                        }
                    }
    }
},
{ $addFields: { attributes_unwind: "$attributes" } },
{ $addFields: 
    { attributes_unwind: 
        { $cond :
            [
            {
                attributes_unwind :{ $elemMatch:{key:"age"}}
            },
            "$attributes_unwind",
            { $concatArrays: [ "$attributes_unwind", [ {"key":"age","value":""}] ] } 
            ]
        }
    }
},
{ $unwind: "$attributes_unwind" },
{ $match: {"attributes_unwind.key": "age"}},
{ $sort: {"attributes_unwind.value": 1}},
{ $project: {"attributes_unwind": false}}
 ])

But if gives an error 
Error: command failed: {
    "ok" : 0,
    "errmsg" : "Unrecognized expression '$elemMatch'",
    "code" : 168,
    "codeName" : "InvalidPipelineOperator"
} : aggregate failed 

A:

I solved this by filter -> size -> gt -> cond. Sharing the solution here. I am open on feedback on coming up with a better query
db.getCollection('students').aggregate([
{
    $match: {
attributes: { 
                    $elemMatch: {
                        value: {$gte:10},
                        key:"marks"
                        }
                    }
    }
},
{ $addFields: { attributes_unwind: "$attributes" } },
{ $addFields: 
    { attributes_unwind: 
        { $cond :
            [
            { $gt:[{ $size:{
                $filter: {
                    input: "$attributes_unwind",
                    as: "keyVal",
                    cond: {
                        $eq : ["$$keyVal.key","age"]
                        }
                    }
            }},0]},
            "$attributes_unwind",
            { $concatArrays: [ "$attributes_unwind", [ {"key":"age","value":""}] ] } 
            ]
        }
    }
},
{ $unwind: "$attributes_unwind" },
{ $match: {"attributes_unwind.key": "age"}},
{ $sort: {"attributes_unwind.value": 1}},
{ $project: {"attributes_unwind": false}}
 ])

