Now that we got the basic field operators set, let's see how we can work with arrays because there are
some nice operators that help us with updating existing arrays in documents, like the hobbies array in my
users,
so I switch back to that users collection
we worked with before.
Let's say we want to update all documents,
so Chris, Anna, Max, whoever matches, all documents where the person has a hobby of sports with a frequency
greater or equal to three, this also practices something we used in the read section.
So how could this look like?
Well we want to first of all find all the persons so that we get a feeling for the correct filter we should
write,
so I want to find a certain amount of persons and I want to find persons based on the hobbies array
and then on the hobbies array, I got two conditions. Two conditions on the same field means that I need
and and then here, the first condition is that for hobbies.title,
I want to have sports and the second condition is that for hobbies.frequency, I want to have a value greater
or equal to three.
Now if I now hit enter, we get Chris, sports frequency five, makes sense, we get Anna, sports frequency
two.
Well we've been there, right, we've been in that situation
in the read module, if you haven't been there, you should go there now.
Now how did this happen?
This simply checks for documents where you have a hobby with a title of sports and where you have a hobby
with a frequency greater or equal to three
and that is the case for Anna,
she has a hobby with the title of sports and she has a hobby with a frequency of three or greater or equal
three.
Now of course, we're looking for one and the same document but we are not expressing this in this query.
The correct query would be to use elemMatch,
so there we would normally say hobbies should have a value which is a document where we use elemMatch
and elemMatch is now looking at the elements and hobbies which happened to be embedded documents,
so now we can say the title key should be sports and for that same embedded document, the frequency should
be greater or equal to three.
And if I now hit enter, we find Chris because we have sports with the frequency greater or equal to
three and we find Max where the same is true,
Anna is not part of the results set anymore. So this is the right query to find the documents I want
to update.
Now let's say this document is the document I want to update
but then, I want to update that document in the array,
so essentially I know which overarching document is what I want to change but then in the document,
I want to change something in exactly that element which I found in the array.
Now we can do that, I'll quickly count here so that this stays on the same page, we can do that with update
many because we'll have potentially and also in reality more than one result, I can now copy that whole
query here because that is the query I need down there
and now how do I want to update this? By default if I now use $set and then define something here,
these are of course changes that will be applied to the overall document,
so to the overall person, not to the document in the array which I found. If I want to update that array
document, I can use a different syntax, I can use set,
that is correct but then in here, I don't want to update hobbies as a whole,
I don't want to assign a brand new value to hobbies,
I only want to update the element in hobbies which matched my condition here. And to do that, we can use
a different syntax,
I can enclose it in quotation marks and say hobbies.$ and this will automatically refer
to the element matched in our filter,
so in our query and then here, I can define the new value.
So here I could now say that should still have a title of sports, that should still have a frequency of,
well of
what? I could do that but the frequency of course differs, it's five for Chris and three for Max and I don't
want to override it, essentially I don't want to override the entire document here,
instead what I want to do is I want to add let's say a new field and we can do that by moving back to
hobbies.$
and dot something else, we could add a new field here, we could say dot high frequency and
set this to true as a value.
So what this will do is it will dig into hobbies, find the element which we found in our query and then
access the high frequency field which if it doesn't exist simply gets added. If I now hit enter,
you see it matched two documents, two persons and it modified two persons
and if we now have a look at all persons again, we see that Chris still has sports and five but also
high frequency true,
Anna was not edited because she had a low frequency here and therefore was not selected in our query,
Manuel doesn't have sports at all
but Max also has sports and now also got the high frequency field.
So this dollar sign placeholder
here is a great helper
when you have a query where you do select a specific element in an array and you then want to update
exactly that element in your set operation.
And just to make it really clear, inside of set, you could of course have updated totally other fields
as well,
you could update this high frequency field and then also update isSporty or the name or add an age
to the overall document.
$set to works as before, it's just this special placeholder which you can use in the path to
a field to quickly get access to the matched array element.