在Mongoose中对嵌套的子文档进行sorting和分组
我有一个架构, 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 ] })
我已经得到了家长的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()
任何帮助实现与replies
子文档相同的结果将不胜感激。 我想以这样的forms返回每个答复的最新APPROVED
版本:
comment: { body: "The comment's body.", user: ObjectId(...), replies: [ { body: "The reply's body." user: ObjectId(...) } ] }
基本上你只需要从现有的pipe道上继续相同的过程。 但是这次要$unwind
退出“版本”每个“答复”条目和$sort
在那里。
所以这些是你的pipe道的“额外”阶段。
// 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" } } }}
所有这些都取决于你想要的领域,无论是从Reply
还是从Version
。
无论哪个领域,因为你“解开”了两个数组,所以你$group
back”两次。
-
每次
Reply
sorting后,一次获取$first
项目 -
再次使用
$push
重构"replies"
数组
这就是这一切。
如果你仍然在寻找不使用$unwind
方法来“sorting”数组,那么MongoDB就不会这么做。
在您的devisebuild议位
作为一个说明,我看到你要去哪里,这是你想要的使用types的错误模型。
将“修订历史”存储在embedded结构中是没有意义的。 你很less在一般的更新和查询操作中使用它,正如这个例子所示,大多数时候你只是想要“最新”的。
所以只要做到这一点,并存储一个“标志”,表示“修订”,如果真的有必要。 这些数据可以存储在主结构的外部,而且您不必为了得到每个请求的“最新接受的版本”而跳过这些环节。