如何解决MongoDB 聚合与特定字段不匹配
我是 MongoDB 中的 Aggregation
新手,我试图通过举例来理解它的概念。
我正在尝试使用聚合对我的子文档进行分页,但返回的文档始终是所有文档特定字段的整体值。
我想对包含对象 ID 数组的 following
字段进行分页。
我有这个用户架构:
const UserSchema = new mongoose.Schema({
username: {
type: String,unique: true,required: true
},firstname: String,lastname: String,following: [{
type: mongoose.Schema.Types.ObjectId,ref: 'User'
}],...
},{ timestamps: true,toJSON: { virtuals: true },toObject: { getters: true,virtuals: true } });
没有聚合,我可以对following
进行分页,
我有这条路线,通过他们的 username
router.get(
'/v1/:username/following',isAuthenticated,async (req,res,next) => {
try {
const { username } = req.params;
const { offset: off } = req.query;
let offset = 0;
if (typeof off !== undefined && !isNaN(off)) offset = parseInt(off);
const limit = 2;
const skip = offset * limit;
const user = await User
.findOne({ username })
.populate({
path: 'following',select: 'profilePicture username fullname',options: {
skip,limit,}
})
res.status(200).send(user.following);
} catch (e) {
console.log(e);
res.status(500).send(e)
}
}
);
我的分页版本使用聚合:
const following = await User.aggregate([
{
$match: { username }
},{
$lookup: {
'from': User.collection.name,'let': { 'following': '$following' },'pipeline': [
{
$project: {
'fullname': 1,'username': 1,'profilePicture': 1
}
}
],'as': 'following'
},},{
$project: {
'_id': 0,'following': {
$slice: ['$following',skip,limit]
}
}
}
]);
假设我有这个文件:
[
{
_id: '5fdgffdgfdgdsfsdfsf',username: 'gagi',following: []
},{
_id: '5fgjhkljvlkdsjfsldkf',username: 'kuku',{
_id: '76jghkdfhasjhfsdkf',username: 'john',following: ['5fdgffdgfdgdsfsdfsf','5fgjhkljvlkdsjfsldkf']
},]
当我为用户 john: /john/following
测试我的路由时,一切都很好,但是当我测试没有任何以下内容的不同用户时:/gagi/following
,返回的结果与john 的以下聚合似乎与用户名不匹配。
/john/following
|以下:2
/kuku/following
|以下:0
汇总结果:
[
{
_id: '5fdgffdgfdgdsfsdfsf',...
},{
_id: '5fgjhkljvlkdsjfsldkf',...
}
]
我希望 /kuku/following
返回一个空数组 [] 但结果与 john 的相同。实际上,我测试的所有用户名都返回相同的结果。
我认为我的实现一定有问题,因为我才刚刚开始探索聚合。
解决方法
Mongoose 使用 DBRef 能够在检索到字段后填充该字段。
DBRefs 只在客户端处理,MongoDB 聚合没有任何操作符来处理这些。
聚合管道返回所有用户的原因是查找的管道没有匹配阶段,因此集合中的所有文档都被选中并包含在查找中。
那里的示例文档显示了一个字符串数组而不是 DBRefs,这不适用于 populate
。
本质上,您必须决定是使用聚合还是填充来处理连接。
对于填充,请使用示例架构中所示的 ref
。
对于聚合,存储一个 ObjectId 数组,以便您可以使用查找与 _id
字段链接。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。