我有两个集合作为用户和用户_课程.user_courses集合是一个多对多连接表.我需要通过注册的分页当然过滤用户.

用户集合如下所示:

[
    {
        "_id": ObjectId("123"),
        "name": "Lorem Ipsum",
        "email": "lorem@ipsum.com"
    },
    {
        "_id": ObjectId("234"),
        "name": "Lorem Ipsum",
        "email": "lorem@ipsum.com"
    },
    {
        "_id": ObjectId("345"),
        "name": "Lorem Ipsum",
        "email": "lorem@ipsum.com"
    },
    ...
]

和User_Course集合类似于:

[
    {
        "_id": ObjectId("12345"),
        "userId": ObjectId("123"),
        "courseId": ObjectId("111"),
    },
    {
        "_id": ObjectId("23456"),
        "userId": ObjectId("123"),
        "courseId": ObjectId("222"),
    },
    {
        "_id": ObjectId("34567"),
        "userId": ObjectId("123"),
        "courseId": ObjectId("333"),
    },
    {
        "_id": ObjectId("45678"),
        "userId": ObjectId("234"),
        "courseId": ObjectId("222"),
    },
    {
        "_id": ObjectId("56789"),
        "userId": ObjectId("345"),
        "courseId": ObjectId("111"),
    },
    {
        "_id": ObjectId("67890"),
        "userId": ObjectId("345"),
        "courseId": ObjectId("222"),
    },
    ...
]

下面是我的代码:

const filterObj = {
    "$or": [
        {
            "name": {
                $regex: searchKey
            }
        },
        {
            "email": {
                $regex: searchKey
            }
        }
    ]
}

Users.aggregate([
    { $match: filterObj },
    { $sort: { createdAt: -1 } },
    { $skip: skip },
    { $limit: limit },
    {
        $lookup: {
            from: 'user_courses',
            localField: '_id',
            foreignField: 'userId',
            as: 'userCourses',
            pipeline: [
                {
                    $match: {
                        $expr: {
                            $and: [
                                {
                                    $eq: [
                                        "$courseId",
                                        new mongoose.Types.ObjectId(courseId)
                                    ]
                                }
                            ]
                        }
                    }
                }
            ]
        }
    },
    {
        $unwind: "$userCourses"
    }
])

使用此代码,它将获取前10个项目(限制:10,跳过:0),然后使用管道中的匹配过滤结果.如果我删除展开选项,它只在查找值内应用过滤器,并返回所有用户,即使userCourse查找为空.

如何在排序、跳过和限制之前按已注册课程过滤用户?

推荐答案

一种 Select 是在$lookup之后应用$skip$limit:

db.users.aggregate([
  {$match: filterObj},
  {$sort: {createdAt: -1}},
  {$lookup: {
      from: "user_courses",
      as: "userCourses",
      localField: "_id",
      foreignField: "userId",
      pipeline: [
        {$match: {"courseId": new mongoose.Types.ObjectId(courseId)}}
      ]
  }},
  {$match: {"userCourses.0": {$exists: true}}},
  {$unset: "userCourses"},
  {$skip: skip},
  {$limit: limit}
])

看看它在playground example号公路上是如何工作的

Mongodb相关问答推荐

MongoDB 4.4如何使用未知密钥更新dict

如何在MongoDB中查找和过滤嵌套数组

mongoose正在抛出Schema的错误has';t已在next.js中注册

执行聚合以消除重复并获得唯一计数

Mongo 将一个数组链接到另一个数组

管道聚合mongodb同一$project阶段的计算字段?

在 MongoDB 中使用 findOneAndUpdate 有条件地更新/更新嵌入式数组

有谁知道这个错误的修复方法(TypeError: Cannot assign to read only property ‘map’ of object '#')

Mongo 删除最后的文件

在 mongoDB 中存储 java 8 LocalDate

使用 MongoDB 进行分页

将 mongoose 字符串模式类型默认值设为空白并使该字段可选

使用 brew upgrade Mongo update from 3.4 to 4.0 报错:在try 升级到 4.0 之前,数据文件需要完全升级到 3.6 版

在 Mongoose 中填写所有必填字段

如何在mongoose中加入两个集合

通过 Java 执行 Mongo like Query (JSON)

我在更新中对 $set 和 $inc 做错了什么

MongoDb 聚合 $match 错误:Arguments must be aggregate pipeline operators

python + pymongo:如何从 for 循环中在 mongo 中的现有文档上插入新字段

Mongoose 为所有嵌套对象添加 _id