Expression is useful if you want to compare two fields inside of one document and then find all documents
where this comparison returns a certain result. Too abstract?
Let's see what it does.
Let's say we have a financial data database and there, I'll quickly prepare a collection, sales and
I'll insert many sales, whoops, with square brackets.
Now the first item has let's say a volume of 100 and a target of 120,
the next item has a volume of 89 and a target of 80
and I have another item where the volume is 200 and a target of 177. So now I inserted three entries here,
we can quickly check them out, check them out with find and then pretty printing,
so these are the three entries.
Now let's say we want to find all entries, all items in this collection where the volume is above the
target,
this is a typical use case where expression can help us,
now how do we use that?
We use it as such,
we access our sales collection and now in there, I specify my filter document and I first of all
use expr which is this expression operator, now expr takes a document describing the expression.
You can then use a couple of comparison operators like gt,
now by the way, check out the official docs to learn more about valid expressions and which operators
you can use there. So gt is one,
now here I pass an array
and it will basically compare all these fields.
Now the interesting thing here is I won't enter values manually to find out which one is the greater
item because that's pretty redundant,
instead here, we now reference names of fields in our data.
Now in our data, remember we have volume and target as fields,
now you don't enter volume and target like this,
this would be invalid
instead you wrap them in quotation marks,
you wrap the data in quotation marks, like this, volume and target,
so now it would compare volume and target and only find documents where volume is greater than target.
However, this would still not work because right now it would still treat this as a hard input from your
site,
so basically as a string and it would compare if volume is greater than target and it would return everything
because from an alphabetic perspective, this is true
and that's probably also nice to know that greater than does work here too.
If we want to refer to the field names, we have to add a dollar sign at the beginning,
this tells mongodb hey please look at the volume field and use the value of that in this expression
and you can't use that in every place in your queries,
it does work on the expression query though and later in the aggregation framework module, you'll find
more places where you can use that.
So now we're referring to the field names
and if I now hit enter, I only find two documents where the volume indeed is higher than the target.
The first document where that was not the case is not included in the results subset and that is of
course super useful because with this dynamic approach, we have an easy time of fetching the data where
some condition within the document is met,
so where two kind of related fields have a certain kind of relation that we check here.
Now there also is a more complex form of expression,
let's say we don't just want to compare whether volume is greater than target but let's say if the volume
is above 190, the difference to target has to be at least 10. So we should still find this document,
the difference is only nine here
but it's also not greater than 190,
for this however, we should also still find it because it will be greater than 190 and the difference
will then be greater than 10 to target
but how will we write this?
For this, you have to adjust the part inside your greater than or whatever your condition here is. The
first value will now be a document and there, you use a special dollar sign cond operator which is related
to expression,
so this cond is related to this expression so both can work in tandem.
The condition allows you to specify document that describes a conditional value which it will derive
here,
so remember, we're still looking for a value we can use as a first element in our greater than array and
we just want to calculate that value dynamically. For that, in that cond document, we first of all specify
a condition with if
and that has to be named if, if is then another comparison operator.
So here we can check for let's say greater than or equal,
again we have two values in here and we want to check whether volume is greater than or equal to 190.
Now if this is met, then make sure to place the comma correctly after a closing square bracket and curly
brace, then we have a certain value we want to use,
so this indeed is named then and we can either hardcode a value here or we calculate it dynamically.
Now here we can calculate dynamically by passing another document and you subtract, which is an operator
you can use to subtract two values,
you specify an array and you could hardcode values to subtract these two values from each other
and by the way subtract and so on, these are all aggregation pipeline operators, so no worries if that
is a lot
right now, in the aggregation framework module, this will all become a bit clearer and also easier. So
subtract will subtract the second element we specified in this array from the first element.
Now what I want to do here is essentially I want to subtract 10 from volume, so that the volume I use
for comparison is reduced by 10.
So here I will use volume as a first element and then I subtract 10 hardcoded in there,
ok so I subtract 10 from the value that is stored in the volume
for all the items where the volume is greater than 190. Now that's one case,
now let's add an else case because what is the case for items where the volume is not greater than
or equal to 190?
Well there, I'll simply just use the volume without any changes, like this.
So now we finished our condition and that is the first value in our array here,
so the first value is
now simply either the volume or if the volume is greater than or equal to 190,
it's the volume minus 10,
so for our volume of 200, we'll compare one of 190. Now the value we compare it to
and now I'm in the array related to the greater than operator, the value I will compare it to still is target
here.
Now if I hit enter, I do find the same set of data as before but this will change if I switch the 10 which
I subtract from my volume to let's say 20, that I require a difference between volume, to 30, that I
require a difference of volume to target of 30 if the volume is 190 or higher.
Now I only get back this element with a volume of 89 because it's not as high,
it's not making it into this comparison here
and therefore I take the volume unchanged to compare it to the target value.
But for this document, the volume is 200
hence it makes it into this condition and into this then block, therefore the volume I take for comparison
is reduced by 30
and that is then not greater than the target of 177 anymore because 200 minus 30 is of course 107
.
Now this is a quite complex case here
and this is also not a query you might be running all the time but it can be very helpful.
Now for all the comparison and change operators which we used in there, again this is something you'll
also see in the aggregation framework module and it is something where you can dive into the official docs
to see all possible values there.
This is a quite powerful command and therefore definitely worth playing around with
but for now, I just wanted to explain how it generally works and how you have to think about it.