Is It possible to use query projection on the same collection that has a $elemMatch projection?

后端 未结 1 847
你的背包
你的背包 2021-01-26 13:12

I understand that you can limit the items in a subcollection array using $elemMatch as a projection. When using it as such it returns all fields of the subdocuments that match r

相关标签:
1条回答
  • 2021-01-26 14:10

    Yes there are two ways to do this. So you can either use the $elemMatch on the projection side as you already have, with slight changes:

    Model.findById(id,
       { "comments": { "$elemMatch": {"created.by": "Jane" } } },
       function(err,doc) {
    

    Or just add to the query portion and use the positional $ operator:

    Model.findOne(
        { "_id": id, "comments.created.by": "Jane" },
        { "comments.$": 1 },
        function(err,doc) {
    

    Either way is perfectly valid.

    If you wanted something a little more involved than that, you can use the .aggregate() method and it's $project operator instead:

    Model.aggregate([
        // Still match the document
        { "$match": "_id": id, "comments.created.by": "Jane" },
    
        // Unwind the array
        { "$unwind": "$comments" },
    
        // Only match elements, there can be more than 1
        { "$match": "_id": id, "comments.created.by": "Jane" },
    
        // Project only what you want
        { "$project": {
            "comments": {
                "body": "$comments.body",
                "by": "$comments.created.by"
            }
        }},
    
        // Group back each document with the array if you want to
        { "$group": {
            "_id": "$_id",
            "comments": { "$push": "$comments" }
        }}
    ],
    function(err,result) {
    

    So the aggregation framework can be used for a lot more than simply aggregating results. It's $project operator gives you more flexibility than is available to projection using .find(). It also allows you to filter and return multiple array results, which is also something that cannot be done with projection in .find().

    0 讨论(0)
提交回复
热议问题