So we're coming closer to the end of this array section but it's really important that you understand
how you can work with these different array stages like unwind and operators that you can then use within
the project phase or the group phase.
So let's say we now wanted to transform our friend objects such that we only output the highest exam score
for every person,
so we no longer have the exam scores array, we still only get three person results but we have no exam
scores in there but only the highest exam score.
Now there probably are multiple ways of achieving this,
definitely feel free to pause the video and try it on your own,
thereafter I will show you one solution I came up with.
So were are you successful?
This is definitely a challenging task.
Now to get the highest possible score, what we need to do is we will need to unwind this array to get multiple
documents per person with the scores being a top level element, so that we can then sort the documents
by the scores and then group them together by person and take the first score that we find for that
person.
So let's do that step by step.
The first phase I'll add here is the unwind phase
and I want to unwind on the exam scores, like this.
Now this will give me many new documents where we have many pairs of persons and their scores.
In the next stage thereafter, I want to sort and I want to sort on exam scores which will not be an
array anymore at this point because of unwind but a single value
and I want to sort in descending order. By the way, you don't use $examScores here because
I'm referring to the field name and not to the value of the field here,
so let's try this.
So now what I get is a bunch of documents and document that the top has the lowest score because what
went wrong?
Well I basically forgot that in exam scores, we have nested objects of course and we don't have the value
itself stored in exam score after unwinding
but the embedded document,
so what can we do?
Well of course we can sort by examScores.score here or let's try alternative, what if we unwind
on exam scores score here?
Well this does not work because the score is not an array,
so this is not something we can do.
We can of course do what I just mentioned and sort on a different field or we add a projection stage in
between where we maybe omit the ID, where we do include the name and age and let's say also, let's say
we leave out the hobbies and I do add a score field here which is exam scores score with a dollar sign
here
so that it take the value of this field. And then here I could sort by score which is now the newly stored
value.
If I take this and I insert it here,
now this looks better,
now we got our unwinded documents and you see that we have sorted them with the highest scores first.
Now we just need to add a group stage,
so what we can do here is we can add group and I want to group by my name of course so that the persons
stay together, we could also group by ID if we kept this included.
Maybe let's do that because names could be duplicated,
IDs won't,
so let's group by _id.
Now I'm using a slightly different syntax than before,
I don't have curly braces Id, like this,
I could absolutely do that but this just adds some extra readability,
in this case since I have the old ID and I keep it as an ID, I think it's readable enough.
So I'm now grouping by ID and if I now copy that, let's see what that gives us,
well it just give us the ID like this, we should use a value here.
So now I just get three objects with the ID,
the other fields are lost which makes sense because grouping well merges the documents together,
so if we want to keep some information, we have to add it in the group stage.
So let's go to the group stage here and there,
I'll add a max score field
and here, we can use the max operator which you can find in the official docs and I'll simply say that
I want to get the maximum based on the score field.
Now let's grab this and execute it
and now you see that I calculate max scores.
Now let's quickly validate if this is correct by checking out all friends here.
So what we have there is that for the first person, Max, the highest score is 88.5
and let's compare IDs,
yes,
this is the ID of Max,
this seems to be correct here.
Now for Manuel, the ID ends with a five, the highest score is 74.3
and this looks good too
and I assume it's also correct for Maria.
So this worked,
we now have our max score.
Now it would also be nice to see the name here,
right
and it would also be nice to not just see the max score like this but to also sort these documents here
in descending order.
Now regarding the name, I'll add a name field here and there's another operator we can use here,
it's the first operator which simply tells mongodb
hey use the first value you encounter
and since the name is the same on all documents for this group, this is perfectly fine.
So I can point at $name here, referring to the name which I had in the input documents
and now to also sort this,
let's add another sort stage here and there,
I will sort for my max score,
so let's sort max score in a descending order.
And now this is my finished pipeline,
let's try it out.
This is looking good,
we have the name in there and we have descending scores.
So this shows you hopefully how you can work with arrays and how you can combine the different pipeline
phases to split arrays up, to pull array values out of there, to then group them together and so on.