MongoDB: find and findOne with nested array filtering

前端 未结 1 675
耶瑟儿~
耶瑟儿~ 2020-12-04 01:05

This little task turned out to be harder than I thought.

Consider the following very simple Posts collection. Suppose I want to display all the posts, coupled with o

相关标签:
1条回答
  • 2020-12-04 01:33

    I'll TL;DR since this turned out to be a hell of a ride. I've tried $elemMatch, I've tried $redact (also with $$CURRENT and $$ROOT), I've tried $map, I've tried the aggregation framework, I've tried $project.

    You can read all about it here: https://www.devsbedevin.net/mongodb-find-findone-with-nested-array-filtering-finally/

    TL;DR

    The solution seems to be to use the aggregation framework to filter the array and override the comments property with the results. This is simpler than it sounds:

    db.getCollection('posts').aggregate(
        {$match: {"author.id": authorId}},
        {$addFields : {"comments":{$filter:{ // We override the existing field!
            input: "$comments",
            as: "comment",
            cond: {$eq: ["$$comment.state.deleted", false]}
        }}}}
    );
    

    The result:

    {
      "author": {},
      "message": "This is post1",
      "comments": [
        {
          "message": "Im number 1!!!",
          "state": {
            "deleted": false
          }
        },
        {
          "message": "tHIS IS GREAT!",
          "state": {
            "deleted": false
          }
        },
        {
          "message": "I can type better than you guys",
          "state": {
            "deleted": false
          }
        }
      ]
    },
    {
      "author": {},
      "message": "This is post 2",
      "comments": [
        {
          "message": "I wanna have your children",
          "state": {
            "deleted": false
          }
        }
      ]
    }
    
    0 讨论(0)
提交回复
热议问题