Now here is the data
as we have it in our dataset again.
Now let's have a look at a different pipeline stage that allows us to transform every document instead of grouping
multiple together
and that will be the project stage.
Now we already know projection from the find method,
well as an aggregate stage, project became more powerful,
so what can project do for us?
Let's now start simple and not have any other set, I should say we don't do any filtering,
we just want to transform every document.
Then we can use the project stage and as all stages, the value for $project here is simply a document
where you well configure that stage so to say
and in its most simple form, project works in the same way as the projection works in the find method.
So you can for example say I don't want to have the ID by setting it to zero here,
you could say I only want to have the gender, I want to have the name field and location and email but
I want to reformat some of these fields. So including gender is simple,
we just add a one
but let's say the name should be different
now, let's say the name should be one field instead of this embedded document
and this is something we can easily do with this project stage.
We can add new fields here which is a cool feature and we could add the full name field and that full
name field could then simply be created on the fly based on the nested name first and name last fields.
Now how would that work?
There is a special operator we can use and you'll find that in the official docs, a full list to all the
operators can be found in an article after this lecture.
So you can use a special operator, so you pass an object first of all to full name because we're going
to perform an operation
and then here, we'll use concat. Concat, $concat allows you concatenate two strings and you
simply pass an array here which contains the two strings.
Now you could hardcode some values in here like hello world,
that is also possible,
you can work with hardcoded data. If I now
copy that,
you'll see every person is named HelloWorld, concatenated together like this,
also note that there is no whitespace in between.
This is of course something you can do but most likely, this is not the result you want to have.
So instead what we want to do is we want to refer to the first and last keys here
in the name field,
so what we can do for that is we can use a special syntax again in a string
and the quotation marks are important, with a dollar sign,
we can refer to name first.
Now the dollar sign just simply tells mongodb that this is no hardcode text which it should
take like this but that this refers to a field of the incoming document and that it should take the
value of that field instead
and in this case, it's just an embedded field,
it could also be a normal field, a non-embedded one. So we can have the first name,
then let's say we add a whitespace in-between
and then here, we use name last to refer to this name here.
If we now take this code and we run that, we indeed get back documents, the same amount of documents as
before by the way
because unlike group, project does not group multiple documents together, it just transforms every single
document and therefore we get the same amount of documents
but with a totally different data
and the interesting part of course is that we cannot just include and exclude data but that we can even
add new fields with hardcoded values if we want to do or in our case, with a derived value derived from
the data that was in the document before.
Now let's say we also want to make sure that the first and last names start with uppercase characters
and we can do that too with the projection phase,
I'll just restructure this real quick to make it a bit easier to read,
we'll have to make sure to move these up later.
So right now, we just concatenate our first and last names
but of course we could transform these first and last names too before we concatenate them, so we can
pass more complex expressions to concatenate essentially. The first name can be an expression described
in a document and so can the last name.
So in the first name here, we can use $toUpper which is another operator offered by
mongodb
and to upper can simply receive the field which it should turn into uppercase, so name first.
Now it's the same syntax I need for the last element which we concatenate together, just add its
name last here. Now to upper, this expression here and this expression, these will return strings so concatenate
will still work on three strings, just that the first and the last one are also well transformed by us.
Let me now move these two methods up and let's copy that,
if we now run our aggregation, well everything is uppercase
now, certainly a change but what if we only want to work with the first characters?
Well then we drill into that further.
Now we don't just run to upper on the entire first name or entire last name
instead we want to run it on just the first character of these names and then we want to append the rest
of that word in
well the normal casing. For this, the thing which I transform with to upper is the result of yet another
expression wrapped into a document,
you see a pattern here, all these expressions are always wrapped into documents.
Now there I use another operator, the substrCP operator which returns the substring of well a string,
so a part of a string.
SubstrCP takes an array,
the first argument is the string,
so here, I now use name first.
The second argument is the starting character of your substring, this will be zero
because strings are is zero indexed,
so this is the first character of the string and then it asks you for how many characters should be included
in the substring
and that should be one here,
so just the first character.
Now this will turn the first character of the name into an uppercase character,
of course we don't just want to have the first character of the name,
we also want to have the other characters, just not converted to uppercase.
So I will add an additional element to the concat array and that should now be the rest of the first
name because here, we're extracting the first character and we're converting it to uppercase,
now we need the rest of that name. For that,
I'll again use my substring CP operator here because I need a substring of name first,
I just need the other
well half or
well the rest of it and therefore, I start at character 1
but now of course I need to find out how many elements I need and for that, I need to dynamically derive
how long the name is and we can do this with another expression and it's not uncommon to have nested
and more complex stages like this one.
So don't worry if this looks very frightening,
obviously this is a more complex transformation we're doing here but I find it super important for you
to understand how you can work with all these expressions and operators, especially in the project phase
where you do a lot of transformations typically.
So now here, what I want to do is I want to use another operator, the subtract operator which simply
returns the difference of two numbers,
now why do I need that?
Because the numbers are passed in array here because I need to find out the length of my name and then
subtract one of that because we start after the first character in this substring.
So here, I will now use another operator, strLenCP which calculates the length of a string and there,
I point at name first
again and then, I subtract one from that,
so this is the second element in the subtract array.
Ok so this is quite a complex operation
but in the end what I do here is I simply retrieve the rest of the name by starting after the first
character
and then I find out how long that name is if I well reduce it by the one character,
so if I subtract that one starting character.
Now previously we had Gideon Van Drongelen,
let's now repeat this for the last name and see if we have Gideon Van Drongelen where only the
first character is an uppercase character.
So let me grab this entire code and let's replace this code with it
and now we just need to replace name first with name last in all three places and that should be it.
Let's now move pretty up and aggregate up and copy that entire command,
let's move over and execute it
and this looks much better.
Now we have only the first characters of each name
converted to uppercase characters and you'll learn a lot about operators and how you typically work with
them and combine them especially in the project phase which is all about transforming data.