Alright, let's take some time now and talk about the
unwind aggregation operator. In a lot of situations we're going
to want to count or do some other sort of
operation based on the values in an array field. We
need to use array field values in some way. So,
with this data We might want to answer a question like
the following: In our collection, who included the most user
mentions in their tweets? Now the reason why this is
relevant to the unwind operator is because user
mentions are included in our tweets inside an array
field. Now in this data, if you remember,
user mentions are found within the entity's sub-document, in
particular, in the user mentions field. User mentions
is an array that contains documents that represent each
individual user mention. So, what I'm going to do
here is pull up some examples using this query.
Now, here I'm using an operator that we haven't seen
before. All this says is give me back documents where
the user mentions field of the entities sub-document are of
length three. So, I'll pretty print this. Then, if we scroll
up, we can see that this example here does in
fact have three user mentions in it. And, just so
you have the full picture, entities, is a top level
field here. It has a sub document as a value and
user mentions is one of the fields of that
entities sub document. User mentions is an array value
field. And, we can see that it holds documents
that are shaped liked this Now, what we're interested in
are these screen names here, because these are the
names of users that are mentioned in this particular tweet.
And for any tweet that mentions a user, you're
going to have an array with documents like this inside
of it, naming the users mentioned. Now, what we want
to find out is a count of all the user mentions
made by an individual Twitter user. So what we're going to
have to do is look through all of the tweets. There'll
be some grouping involved, of course, because we want to
group together tweets by the same user. But we also want
to count the number of user mentions. Unwind is a convenient
tool for doing that to answer this particular question. Let's take
a look. Okay, so here's our aggregation pipeline.
Our first stage uses the unwind operator and it's
being run against that user mentions field. Now
remember that what unwind does, is creates a copy
of the containing document for any array field.
It duplicates all fields except for the items in
the array. And it will create one copy for
each element in the array. And the only difference
between all of the copies will be that this field
Will take on each of the different values in the array,
in the documents that are produced. So let me, let
me make this a little bit more concrete. If we take
a look at this again, for this particular tweet, the
unwind stage will produce three documents as output for this one
tweet document here. All of the other fields that we
see here, all of these, And everything else here in this
tweet document will be exactly the same. The one difference will be
that the user mentions field will have a single document as its
value in each of those three copies of this tweet. In the
first copy, it will have this as its value In the second copy,
it will have this and finally the third copy, it
will have this. So, in the documents that get passed along
to the next stage, in this case a group stage,
the documents will have a different value for the user mentions
field. Now, it turns out that in our case. What
we really care about is this splitting effect. Not so much
with the value of user mentions is each time through.
Because, what we're interested in doing in the next stage is
essentially counting all of the documents that
pass through to this group stage with the
same screen name for the user who created
the tweet. Because, again, remember. The question we're
after here is, who included the most user mentions in their tweets? So by the
time we get to this stage unwind will
have produced an individual document for every user
mention in the collection. And group then will
aggregate them together based on the screen name
of the user who created the tweet, will
then simple produce a count field here as
part of our group operation. And again remember
that sum imply increments this counter each time
you see the document that's aggregated together with
the screen name or a document that has
the same screen name. Then we do our sort
and limit states. So one question I'll put to you
here is does this count the number of unique
user mentions? That is to say if a twitter user
mentions the same user more than once does this
count each one of those mentions or does it count
all mentions of the same user as one mentions? If
its not unique mentions that are not being counted here
question I'll leave you with is what type of
aggregation pipeline would we need to put together in order
to count unique mentions. Of users. Okay, so let's
run this. And because we limited this to one, we
get one document in our result array with a
count of 21 for user mentions for this user. Now
in case it's not clear to you by this
point, the advantage of the aggregation framework in MongoDB is
that all of this work is being performed
server side. That means that for this particular query
all that comes across the network to our
client is just that one result we just looked
at. The aggregation framework is powerful, not just
because of the functionality it provides, but because of
the speed with which it can execute these queries
because this functionality is fundamental to the server itself.