Also…that human field do you mean to check is it’s empty string, null or does not exist, which are all different scenarios in MongoDB (which can be confusing, especially the way things like Oracle deal with empty strings…unless it’s just me that finds that annoying)
Since $unwind is the last stage, it would be preferable in terms of network I/O to forgo this last stage. An $unwind stage increase the amount of data transferred because all data outside the $unwind array is duplicated for each element of the array. You could use $project to remove duplicated values that are not required.
I think that your $match should use an $elemMatch because I suspect that you want both conditions to be true for the same message.
I also think that you would want a $set stage with $filter on messages to only get the matching elements.
By not exporting 100K documents by using the aggregation framework to do what ever computation you do with 100k on the server rather than the client.