mongo/mongoose:聚合:查找*不*在数组字段中有引用的文档?

时间:2021-03-27 18:35:01

标签: mongodb mongoose pipeline aggregation

给定一个“艺术品”模式(省略其他字段)...

ArtworkSchema = new Schema({
  ...
  ratings: [{ type: Schema.Types.ObjectId, ref: "Rating" }],
  ...
});

和“评级”模式......

   RatingSchema = new Schema({
      ...
      artwork: { type: Schema.Types.ObjectId, ref: 'Artwork' },
      user: { type: Schema.Types.ObjectId, ref: 'User' },
      ...
    })

和“用户”模式...

   UserSchema = new Schema({
      ...
    });

用户对艺术作品进行“评分”,并创建评分文档。

我需要找到所有未被用户评分的作品。

我的问题:我不知道如何组成一个聚合管道,我可以在其中找到所有在特定用户的 ratings 数组中不包含 Rating 的 Artwork 文档。

我已经能够编写一个可以在 artwork.ratings 数组中找到特定用户的管道,但我不知道如何从返回的结果中排除该 Artwork 文档。< /p>

这是我目前的管道:

Artwork.aggregate([
    {
      $lookup: {
        from: "ratings",
        localField: "ratings",
        foreignField: "_id",
        as: "ratings",
      },
    },
    {
      $unwind: {
        path: "$ratings",
      },
    },
    {
      $lookup: {
        from: "users",
        localField: "ratings.user",
        foreignField: "_id",
        as: "ratings.user",
      },
    },
    {
      $unwind: {
        path: "$ratings.user",
      },
    },
    {
      // this will remove items from 'ratings' array, but not the root Artwork doc
      $match: "ratings.user._id": { $nin: [ObjectID("60483532b8c09b0015454be7")] },
    },
    {
      $group: {
        _id: "$_id",
        root: {
          $mergeObjects: "$$ROOT",
        },
        ratings: {
          $push: "$ratings",
        },
      },
    },
    {
      $replaceRoot: {
        newRoot: {
          $mergeObjects: ["$root", "$$ROOT"],
        },
      },
    },
    {
      $project: {
        root: 0,
      },
    },
  ]);

'$match' 阶段将从 'Artwork.ratings' 数组中删除 'rating' 项目,其中 rating.user._id === ObjectID("60483532b8c09b0015454be7"),但最终的 Artwork 文档仍然返回结果。

有没有一种方法可以添加/修改流水线阶段,以便过滤掉具有特定用户评级的任何艺术品?

或者,是否有完全不同的方法?

感谢任何帮助!

0 个答案:

没有答案