 <p>Using <code>$unwind</code> and then <code>$group</code> with the tag as the key will give you each tag in a separate document in your result set: </p> <pre><code>db.collection_name.aggregate([ { $unwind: "$tags" }, { $match: { "tags.type": "machine" } }, { $group: { _id: "$tags.code" } }, { $project:{ _id:false code: "$_id" } } ]); </code></pre> <p>Or, if you want them put into an array within a single document, you can use <code>$push</code> within a second <code>$group</code> stage: </p> <pre><code>db.collection_name.aggregate([ { $unwind: "$tags" }, { $match: { "tags.type": "machine" } }, { $group: { _id: "$tags.code" } }, { $group:{ _id: null, codes: {$push: "$_id"} } } ]); </code></pre> <p>Another user suggested including an initial stage of <code>{ $match: { "tags.type": "machine" } }</code>. This is a good idea if your data is likely to contain a significant number of documents that do not include <strong>"machine"</strong> tags. That way you will eliminate unnecessary processing of those documents. Your pipeline would look like this:</p> <pre><code>db.collection_name.aggregate([ { $match: { "tags.type": "machine" } }, { $unwind: "$tags" }, { $match: { "tags.type": "machine" } }, { $group: { _id: "$tags.code" } }, { $group:{ _id: null, codes: {$push: "$_id"} } } ]); </code></pre>