Mongoose 聚合 - $filter 不删除匹配元素

问题描述 投票:0回答:1

我有以下查询,应将用户的

privacyStatus
更新为某个值,并删除所有
notifications
ObjectIds
的数组),其中
type
属性等于该值:
follow_request
.

 User.aggregate([
            {
                $match: { _id: new mongoose.Types.ObjectId(req.user._id) },
            },
            {
                $lookup: {
                    from: "Notification",
                    localField: "notifications",
                    foreignField: "_id",
                    as: "notifications",
                },
            },
            {
                $set: {
                    privacyStatus: value,
                    notifications: {
                        $filter: {
                            input: "$notifications",
                            cond: {
                                $ne: ["$$this.type", "follow_request"],
                            },
                        },
                    },
                },
            },
    
            {
                $merge: {
                    into: "users",
                },
            },
        ]).then((result) => {
            res.send("Done")
        })

privacyStatus
已在数据库中成功更新,因此我知道
$match
阶段工作正常,但是
notifications
数组根本不会更新即使有与过滤器匹配的通知

我的用户模型:

{
  privacyStatus: {type: Boolean},
  notifications: [type: mongoose.Schema.Types.ObjectId,ref: "Notification",]
}

通知模型:

{
   type: {type: String, default: "follow_request"}
}

为什么我的

follow_request
类型的通知没有从用户
notification
数组中删除?谢谢

样本文件: 用户文档:

{
   _id: ObjectId('66324110da2f0f7175ca1949'),
   username: "sam",
   notifications: [
      ObjectId('663c1c0bd0sa68fae7cf6ad2')
   ]
}

通知文件:

{
   _id: ObjectId('663c1c0bd0sa68fae7cf6ad2'),
   type: "follow_request"
}
mongodb mongoose aggregation-framework
1个回答
0
投票

要让您的

aggregate
将结果合并回
users
集合中,您需要做两件事:

  1. $lookup
    中使用的集合从
    Notification
    更改为
    notifications
  2. 认识到您的
    User.notifications
    字段是
    ObjectId
    的数组。当您的
    $filter
    返回结果时,您将无法将它们
    $merge
    返回到您的
    User.notifications
    数组中,因为它们将是完整的
    Notification
    文档。这可以通过
    $map
    阶段来修复,以跳过每个过滤的
    Notification
    文档并仅返回其
    _id
    。那么这将符合您的架构。

完成的聚合可能如下所示:

User.aggregate([
  {
    $match: {
       _id: new mongoose.Types.ObjectId(req.user._id)
    }
  },
  {
    $lookup: {
      from: "notifications", //< change to this
      localField: "notifications",
      foreignField: "_id",
      as: "notifications"
    }
  },
  {
    $set: {
      privacyStatus: value,
      notifications: {
        $map: {
          input: {
            $filter: {
              input: "$notifications",
              cond: {
                $ne: [
                  "$$this.type",
                  "follow_request"
                ]
              }
            }
          },
          as: "n",
          in: "$$n._id"
        }
      }
    }
  },
  {
    $merge: {
      into: "users"
    }
  }
]).then((result) => {
   res.send("Done")
})

请参阅此处了解工作示例。

© www.soinside.com 2019 - 2024. All rights reserved.