Database

db={"videos":[{"_id":"1","name":"1's Video","status":"complete","privacy":"public"},{"_id":"2","name":"2's Video","status":"complete","privacy":"public"},{"_id":"3","name":"3's Video","status":"complete","privacy":"public"},{"_id":"4","name":"4's Video","status":"complete","privacy":"private"},{"_id":"5","name":"5's Video","status":"flagged","privacy":"public"}],"analytics":[{"_id":"1","user":"1","event":"video_impression","data":{"video":"1"}},{"_id":"2","user":"2","event":"video_impression","data":{"video":"2"}},{"_id":"3","user":"2","event":"video_impression","data":{"video":"3"}},{"_id":"4","user":"2","event":"liked_video","data":{"video":"2"}}]}

Query

db.analytics.aggregate([{/** select only the video_impression events*/$match:{event:"video_impression"}},{/** first uniquify your users but you should* probably run this from the users collection*/$group:{_id:"$user",impressioned_vids:{"$addToSet":"$data.video"},/** remove this if you want the user as _id*/user:{"$first":"$user"}}},{$project:{_id:0}},{/** uncorrelated subquery which should only run once* and then is cached*/$lookup:{from:"videos",pipeline:[{$match:{status:"complete",privacy:"public"}},{$group:{_id:null,video_ids:{$push:"$_id"}}}],as:"all_vids"}},{/** put it conveniently into a single list*/$set:{all_vids:{$first:"$all_vids.video_ids"}}},{/** these are the public-complete videos which that user has not seen*/$set:{unimpressed:{$setDifference:["$all_vids","$impressioned_vids"]}}},{/** get rid of the other fields, uncomment to debug*/$project:{user:1,unimpressed:1}}])

Result