MongoDB:使用if条件进行聚合

时间:2020-06-12 12:20:24

标签: mongodb mongoose aggregation-framework

我有两个mongo文档集合(BlogPosts和UsersActivities),一旦用户查看或评论了博客文章,就会在UsersActivities中创建一条记录。博客文章按类型(A,B,...)分类。 UsersActivities.status是一个枚举[“ Viewed”,“ Commented”]

带有一些伪数据的集合:

BlogPosts: [
  { _postId: 1, content: "some text 1", type: 'A'},
  { _postId: 2, content: "some text 2", type: 'A'},
  { _postId: 3, content: "some text 3", type: 'A'},
  { _postId: 4, content: "some text 4", type: 'B'}
]

UsersActivities:[
  { _userId: 1, _postId: 1, status: "Viewed"},
  { _userId: 1, _postId: 1, status: "Commented"},
  { _userId: 1, _postId: 2, status: "Viewed"},
  { _userId: 1, _postId: 4, status: "Viewed"},
  { _userId: 2, _postId: 1, status: "Viewed"}
]

我正在尝试编写一个查询,该查询将返回所有类型为A的博客帖子的独特列表,并且每个帖子的状态为userId 1(如果查看和评论了帖子,则状态应为“已评论”。找到的状态应该是一个空字符串)。查询结果应如下所示:

[
  {_postId: 1, content: "some text 1", type: 'A', status: "Commented"},
  {_postId: 2, content: "some text 2", type: 'A', status: "Viewed"},
  {_postId: 3, content: "some text 3", type: 'A', status: ""}
]

这是我到目前为止编写的代码,但是我被卡住了,不知道如何进行。

BlogPosts.aggregate([
  {
    $lookup: {
      localField: "_postId",
      from: "UsersActivities",
      foreignField: "_postId",
      as: "UsersActivities",
    },
  },
  {
    $match: {
      type: "A",
    },
  },
  {
    $unwind: {
      path: "$UsersActivities",
      preserveNullAndEmptyArrays: true,
    },
  },
  {
    $match: {
      $or: [
        {
          "UsersActivities._userId": _userId,
        },
        {
          "UsersActivities._userId": null,
        },
      ],
    },
  },
])

请告知,我怎样才能达到要求的结果

1 个答案:

答案 0 :(得分:0)

您可以将Project Aggregation运算符与 MongoDB switch 语句

一起使用
{
    $project: {
        content: 1,
         ....
        {
            UsersActivities: {
                {
                    status: {
                        $switch: {
                            branches: [{
                                    case: {
                                        $eq: ['$UsersActivities.status', 'Commented']
                                    },
                                    then: '$UsersActivities.status'
                                },
                                {
                                    case: {
                                        $eq: ['$UsersActivities.status', 'Viewed']
                                    },
                                    then: '$UsersActivities.Viewed'
                                }
                            ],
                            default: ""
                        }
                    }
                }
            }

        }
    }
}