I don't have a mongoose setting to do this with node, but you can also get the result you want to use in the new aggregation structure in 2.2 - here is an example that gives you the result you wanted. Firstly, my doc example is as follows:
> db.foo.findOne() { "_id" : ObjectId("50472eb566caf6af6108de02"), "items" : [ 1, 2, 3, 45, 4, 67, 9, 4 ] }
To get what you want, I did this:
> db.foo.aggregate( {$match : {"_id": ObjectId("50472eb566caf6af6108de02")}}, {$unwind : "$items"}, {$match : {"items": {$in : [1, 67, 9]}}}, {$group : {_id : "$_id", items : { $push : "$items"}}}, {$project : {_id : 0, items : 1}} ) { "result" : [ { "_id" : ObjectId("50472eb566caf6af6108de02"), "items" : [ 1, 67, 9 ] } ], "ok" : 1 }
To explain, in detail I will take it line by line:
{$match : {"_id": ObjectId("50472eb566caf6af6108de02")}}
This is pretty obvious - this is basically the equivalent of regular search criteria, the results are passed to the next step in the pipeline that needs to be processed. This is the part that can use indexes, etc.
{$unwind : "$items"}
This will cause the array to explode, creating a stream of documents, one for each element in the array.
{$match : {"items": {$in : [1, 67, 9]}}}
This second match returns only the documents in the list, basically reducing the flow of documents to a set of three results.
{$group : {_id : "$_id", items : { $push : "$items"}}}
We want our output to be an array, so we must cancel the cancellation above when we have selected the elements we need, using _id as the key to the group. Note: if you match again, the values will be repeated if you need a unique list that you would use $addToSet instead of $push
{$project : {_id : 1, items : 1}}
Then, finally, this projection is really not needed, but I turned it on to illustrate the functionality - you could not return _id if you want, etc.