如何在 mongodb 中查找和项目聚合后排序?
how to sort after lookup and project aggregation in mongodb?
我有 2 个集合,一个供用户使用,另一个供 posts 使用(Posts 集合的用户 ID 为 postedBy)。
在用户集合中,每个用户都有朋友数组,其中有 it.I 中的用户的 _id 想要按排序顺序(按 CreatedAt 排序)获取我的朋友和我的 post 的所有 Post。
这是我的 Userschema,其中我有 mongoose 对象类型的 friends array ref 到用户集合,
我在这里存储朋友的用户 ID。
`//用户架构
const userSchema = new Schema({
profileImg : {
type: String,
},
name: {
type: String,
required: [true, 'Please Enter Your Name!']
},
about: {
type: String,
},
email: {
type: String,
required: [true, 'Please Enter Email!'],
unique: [true, 'Already Registered!'],
match: [/\S+@\S+\.\S+/, 'is invalid!']
},
password: {
type: String,
required: [true, 'Please Enter Your Password!'],
},
friends: [{
type: mongoose.Types.ObjectId,
ref: 'USER'
}],
address: {
line1: {
type: String,
required: [true, 'Please Enter Your Address!']
},
line2: {
type: String
},
city: {
type: String,
required: [true, 'Please Enter Your City!']
},
state: {
type: String,
required: [true, 'Please Enter Your State!']
},
}
}, { timestamps: true })
这是我的 Post 架构,其中 userId 是对用户集合的引用,这里保存了正在上传 post 的用户的 _id。
//POST 模式
const postSchema = new Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "USER",
required: true
},
postImage: {
type: String,
required: [true, 'Please Upload the Image!']
},
caption: {
type: String
},
likes: [likeSchema],
comments: [commentSchema]
}, { timestamps: true })
`
我在做什么:
1st 我通过 _id 找到用户
2nd 从找到用户的朋友数组,在 posts 集合中查找以获得 post 个朋友
第 3 次现在再次使用自己的 _id 在 post 集合中查找拥有 post
第 4 次连接从朋友 post 和用户 post 获得的两个数组作为 Posts
现在,在第 4 步之后,我想按 createdAt 对 Post 进行排序,但它不起作用..
如何排序?
const posts = await User.aggregate([
{
$match: {
_id: mongoose.Types.ObjectId(req.user_id)
}
},
{
$lookup: {
from: "posts",
localField: "friends",
foreignField: "userId",
as: "friendposts"
}
},
{
$lookup: {
from: "posts",
localField: "_id",
foreignField: "userId",
as: "userposts"
}
},
{
$project: {
"Posts": {
$concatArrays: ["$friendposts", "$userposts"]
},
_id: 0
}
}
])
您可以使用 1 次查找而不是 2 次查找。
排序有 3 种方式
- 代码级排序(使用排序函数)
- 使用$unwind $sort and group (if mongo db version is less than 5.2)
- 使用$sortArray(适用于mongodb 5.2+版本)
如果使用第二种方法。
User.aggregate([
{
'$match': {
'_id': mongoose.Types.ObjectId(req.user_id)
}
}, {
'$addFields': {
'users': {
'$concatArrays': [
'$friends', [
mongoose.Types.ObjectId(req.user_id)
]
]
}
}
}, {
'$lookup': {
'from': 'posts',
'localField': 'users',
'foreignField': 'userId',
'as': 'posts'
}
}, {
'$unwind': {
'path': '$posts'
}
}, {
'$sort': {
'posts.createdAt': -1
}
}, {
'$group': {
'_id': '$_id',
'posts': {
'$push': '$posts'
},
'name': {
'$first': '$name'
}
}
}
])
您可以添加最终响应中所需的任何其他字段,就像我添加名称一样。
我有 2 个集合,一个供用户使用,另一个供 posts 使用(Posts 集合的用户 ID 为 postedBy)。 在用户集合中,每个用户都有朋友数组,其中有 it.I 中的用户的 _id 想要按排序顺序(按 CreatedAt 排序)获取我的朋友和我的 post 的所有 Post。
这是我的 Userschema,其中我有 mongoose 对象类型的 friends array ref 到用户集合, 我在这里存储朋友的用户 ID。 `//用户架构
const userSchema = new Schema({
profileImg : {
type: String,
},
name: {
type: String,
required: [true, 'Please Enter Your Name!']
},
about: {
type: String,
},
email: {
type: String,
required: [true, 'Please Enter Email!'],
unique: [true, 'Already Registered!'],
match: [/\S+@\S+\.\S+/, 'is invalid!']
},
password: {
type: String,
required: [true, 'Please Enter Your Password!'],
},
friends: [{
type: mongoose.Types.ObjectId,
ref: 'USER'
}],
address: {
line1: {
type: String,
required: [true, 'Please Enter Your Address!']
},
line2: {
type: String
},
city: {
type: String,
required: [true, 'Please Enter Your City!']
},
state: {
type: String,
required: [true, 'Please Enter Your State!']
},
}
}, { timestamps: true })
这是我的 Post 架构,其中 userId 是对用户集合的引用,这里保存了正在上传 post 的用户的 _id。 //POST 模式
const postSchema = new Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "USER",
required: true
},
postImage: {
type: String,
required: [true, 'Please Upload the Image!']
},
caption: {
type: String
},
likes: [likeSchema],
comments: [commentSchema]
}, { timestamps: true })
`
我在做什么:
1st 我通过 _id 找到用户 2nd 从找到用户的朋友数组,在 posts 集合中查找以获得 post 个朋友 第 3 次现在再次使用自己的 _id 在 post 集合中查找拥有 post 第 4 次连接从朋友 post 和用户 post 获得的两个数组作为 Posts
现在,在第 4 步之后,我想按 createdAt 对 Post 进行排序,但它不起作用.. 如何排序?
const posts = await User.aggregate([
{
$match: {
_id: mongoose.Types.ObjectId(req.user_id)
}
},
{
$lookup: {
from: "posts",
localField: "friends",
foreignField: "userId",
as: "friendposts"
}
},
{
$lookup: {
from: "posts",
localField: "_id",
foreignField: "userId",
as: "userposts"
}
},
{
$project: {
"Posts": {
$concatArrays: ["$friendposts", "$userposts"]
},
_id: 0
}
}
])
您可以使用 1 次查找而不是 2 次查找。 排序有 3 种方式
- 代码级排序(使用排序函数)
- 使用$unwind $sort and group (if mongo db version is less than 5.2)
- 使用$sortArray(适用于mongodb 5.2+版本)
如果使用第二种方法。
User.aggregate([
{
'$match': {
'_id': mongoose.Types.ObjectId(req.user_id)
}
}, {
'$addFields': {
'users': {
'$concatArrays': [
'$friends', [
mongoose.Types.ObjectId(req.user_id)
]
]
}
}
}, {
'$lookup': {
'from': 'posts',
'localField': 'users',
'foreignField': 'userId',
'as': 'posts'
}
}, {
'$unwind': {
'path': '$posts'
}
}, {
'$sort': {
'posts.createdAt': -1
}
}, {
'$group': {
'_id': '$_id',
'posts': {
'$push': '$posts'
},
'name': {
'$first': '$name'
}
}
}
])
您可以添加最终响应中所需的任何其他字段,就像我添加名称一样。