Noa*_*oah 6 javascript mongodb node.js mongodb-query aggregation-framework
我有一个架构,Comment如下所示.这是一个"评论"和"回复"系统,但每个评论和回复都有多个版本.当用户想要查看评论时,我想只返回最新版本status的APPROVED.
const Version = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
body: String,
created: Date,
title: String,
status: {
type: String,
enum: [ 'APPROVED', 'OPEN', 'CLOSED' ]
}
})
const Reply = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
created: Date,
versions: [ Version ]
})
const Comment = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
created: Date,
versions: [ Version ],
replies: [ Reply ]
})
Run Code Online (Sandbox Code Playgroud)
我已让父母Comment用下面的代码显示我想要的内容.但是,我在将该文件应用于子文档时遇到了麻烦Reply.
const requestedComment = yield Comment.aggregate([
{ $match: {
query
} },
{ $project: {
user: 1,
replies: 1,
versions: {
$filter: {
input: '$versions',
as: 'version',
cond: { $eq: [ '$$version.status', 'APPROVED' ] }
}
},
}},
{ "$unwind": "$versions" },
{ $sort: { 'versions.created': -1 } },
{ $group: {
_id: '$_id',
body: { $first: '$versions.body' },
title: { $first: '$versions.title' },
replies: { $first: '$replies' }
}}
])
.exec()
Run Code Online (Sandbox Code Playgroud)
任何帮助实现与replies子文档相同的结果将不胜感激.我想以这样的形式返回APPROVED每个回复的最新版本:
comment: {
body: "The comment's body.",
user: ObjectId(...),
replies: [
{
body: "The reply's body."
user: ObjectId(...)
}
]
}
Run Code Online (Sandbox Code Playgroud)
基本上,您只需要从现有管道继续执行相同的过程即可。但这一次要$unwind列出每个“回复”条目的“版本”以及$sort它们所在的位置。
因此,这些是您的管道的“附加”阶段。
// Unwind replies
{ "$unwind": "$replies" },
// Unwind inner versions
{ "$unwind": "$replies.versions" },
// Filter for only approved
{ "$match": { "replies.versions.status": "APPROVED" } },
// Sort on all "keys" and then the "version" date
{ "$sort": {
"_id": 1,
"replies._id": 1,
"replies.versions.created": -1
}},
// Group replies to get the latest version of each
{ "$group": {
"_id": {
"_id": "$_id",
"body": "$body",
"title": "$title",
"replyId": "$replies._id",
"replyUser": "$replies.user",
"replyCreated": "$replies.created"
},
"version": { "$first": "$replies.version" }
}},
// Push replies back into an array in the main document
{ "$group": {
"_id": "$_id._id",
"body": { "$first": "$_id.body" },
"title": { "$first": "$_id.title" },
"replies": {
"$push": {
"_id": "$_id.replyId",
"user": "$_id.replyUser" },
"created": "$_id.replyCreated", // <-- Value from Reply
"body": "$version.body", // <-- Value from specific Version
"title": "$version.title"
}
}
}}
Run Code Online (Sandbox Code Playgroud)
当然,这一切都取决于您想要哪些字段,是来自那里Reply还是来自Version.
无论哪个字段,由于您“取消缠绕”两个数组,所以您都会$group返回“两次”。
这就是全部了。
如果您仍在寻找不使用 就地“排序”数组的方法$unwind,那么 MongoDB 还没有这样做。
作为注释,我知道您要使用此方法,并且对于您想要的使用类型来说,这是错误的模型。
在嵌入式结构中存储“修订历史记录”没有什么意义。您很少会在一般更新和查询操作中使用它,正如本文所演示的,大多数时候您只需要“最新”。
因此,只需这样做,并在确实必要时存储一个指示“修订”的“标志”。然后,该数据可以存储在主结构的外部,并且您不必跳过这些环节只是为了在每个请求上获取“最新接受的版本”。
| 归档时间: |
|
| 查看次数: |
774 次 |
| 最近记录: |