如何在此查询中使用 $isNull 到 return 空用户数组

How to use $isNull in this query to return empty Users array

给定一个使用时间戳的基本 Mongoose 用户模式(因此默认情况下 createdAt 和 updatedAt 可用),我正在尝试使用聚合构建一个包含分页服务器端的查询。

到目前为止,当数据库中有数据并且任何过滤器都与集合中的任何项目相匹配时,我已经实现了以下效果。

{
    "users": [
        {
            "_id": "61c331f4bd87407c01b81324",
            "bio": "",
            "surname": "Doe",
            "name": "John",
            "verified": true,
            "disabled": false,
            "username": "user1235",
            "score": 1
        }
    ],
    "pagination": {
        "total": 1,
        "limit": 10,
        "page": 1,
        "pages": 1
    }
}

但是,如果没有项目符合条件,这只是 return 一个空数组,丢失分页部分。我的猜测是侧面部分没有像我预期的那样在这里工作。

const findUsersQuery = await this.userModel.aggregate()
            .match(query)
            .sort({ cratedAt: -1 })
            .project({
                password: 0, email: 0, roles: 0, __v: 0,
                facebookId: 0, googleId: 0, createdAt: 0,
                updatedAt: 0, birthday: 0
            })
            .facet({
                total: [{
                    $count: 'createdAt'
                }],
                data: [{
                    $addFields: {
                        _id: '$_id'
                    }
                }]
            })
            .unwind('$total')
            .project({
                users: {
                    $slice: ['$data', ((page * limit) - limit), {
                        $ifNull: [limit, '$total.createdAt']
                    }]
                },
                pagination: {
                    total: '$total.createdAt',
                    limit: {
                        $literal: limit
                    },
                    page: {
                        $literal: page
                    },
                    pages: {
                        $ceil: {
                            $divide: ['$total.createdAt', limit]
                        }
                    },
                }
            })
        return findUsersQuery[0]

我曾尝试在某些地方使用 $ifNull,即使是在 facet 阶段,为了只是 return 0 或一个空数组到 return 相同的结构(保持用户数组和分页片), 无济于事:

.project({
                users: {
                    $ifNull: [
                        {
                            $slice: ['$data', ((page * limit) - limit), {
                                $ifNull: [limit, '$total.createdAt']
                            }]
                        },
                        []
                    ]
                },
                pagination: {
                    total: {
                        $ifNull: ['$total.createdAt', 0]
                    },
                    limit: {
                        $literal: limit
                    },
                    page: {
                        $literal: page
                    },
                    pages: {
                        $ifNull: [
                            {
                                $ceil: {
                                    $divide: ['$total.createdAt', limit]
                                }
                            },
                            0
                        ]
                    },
                }
            })

如何使用 $ifNull(如果这是最好的方法)以便在没有项目符合条件时保持相同的响应结构?像这样:

{
    "users": [],
    "pagination": {
        "total": 0,
        "limit": 10,
        "page": 1,
        "pages": 1
    }
}

非常感谢任何帮助。

你不需要在这里使用$ifNull,你的问题源于$unwind行为。

您想在 $unwind

中使用 preserveNullAndEmptyArrays

New in version 3.2: To output documents where the array field is missing, null or an empty array, use the preserveNullAndEmptyArrays option.

这将保留文档,即使它是“空的”,如下所示:

.unwind({
   path: "$total",
   preserveNullAndEmptyArrays: true
})