MongoDB:find和findOne,嵌套数组过滤

时间:2017-09-20 13:15:54

标签: arrays mongodb mongodb-query aggregation-framework

这个小任务结果比我想象的更难。

考虑以下非常简单的Posts集合。假设我想显示所有帖子,只显示未删除的评论。

即。从comments数组中过滤掉已删除的注释。

由于我每篇文章都有100条删除的评论,有没有办法做这个服务器端?

收藏品:

{
  "author": {},
  "message": "This is post1",
  "comments": [
    {
      "message": "Im number 1!!!",
      "state": {
        "deleted": false
      }
    },
    {
      "message": "YOU MOTHERF****R",
      "state": {
        "deleted": true
      }
    },
    {
      "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": "This is bulls**t",
      "state": {
        "deleted": true
      }
    },
    {
      "message": "YOU MOTHERF****R",
      "state": {
        "deleted": true
      }
    },
    {
      "message": "I hate u!",
      "state": {
        "deleted": true
      }
    },
    {
      "message": "I wanna have your children",
      "state": {
        "deleted": false
      }
    }
  ]
}

1 个答案:

答案 0 :(得分:0)

TL; DR ,因为事实证明这是一个地狱之旅。我已经尝试了$elemMatch,我尝试了$redact(同时还有$$ CURRENT和$$ ROOT),我试过$map,我尝试了聚合框架,我我试过了$project

您可以在此处阅读所有相关信息:https://www.devsbedevin.com/mongodb-find-findone-with-nested-array-filtering-finally/

TL; DR

解决方案似乎是使用聚合框架来过滤数组并使用结果覆盖comments属性。这比听起来简单:

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]}
    }}}}
);

结果:

{
  "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
      }
    }
  ]
}