如何在Mongoose中合并多MongoDB文档视频数组并按时间倒序?
如何用Mongoose合并多个YouTube创作者的视频并按时间倒序排序?
问题描述
我正在尝试编写Mongoose查询,处理存储YouTube创作者及其视频的MongoDB文档,期望返回合并后的所有视频列表,并按时间倒序(最新优先)排列。
当前我的Mongoose查询代码:
return mongoose.model('creators').find({ id: {} })
该查询返回的结果:
[ { "_id": "5b0891a3dcec4912601e32ce", "name": "CaptainDisillusion", "id": "UCEOXxzW2vU0P-0THehuIIeg", "videos": [ { "_id": "5b0891a3dcec4912601e32cf", "name": "Quick D: A Fighter Jet Says Hi", "id": "-NPmBkYb_mY", "date": "2018-05-10T16:30:30.000Z" } ], "__v": 0 }, { "_id": "5b08967b66d8321034176afb", "name": "Curious Droid", "id": "UC726J5A0LLFRxQ0SZqr2mYQ", "videos": [ { "_id": "5b0891a3dcec4912601e32cf", "name": "Guest post bloggers wanted for the Curious Droid website", "id": "sNLvdoValBw", "date": "2018-05-23T16:30:30.000Z" } ], "__v": 0 } ]
我期望得到的结果格式:
"videos": [ { "_id": "5b0891a3dcec4912601e32cf", "name": "Guest post bloggers wanted for the Curious Droid website", "id": "sNLvdoValBw", "date": "2018-05-23T16:30:30.000Z" }, { "_id": "5b0891a3dcec4912601e32cf", "name": "Quick D: A Fighter Jet Says Hi", "id": "-NPmBkYb_mY", "date": "2018-05-10T16:30:30.000Z" } ]
即仅返回合并后的单个视频数组,并按最新优先排序。请问是否可以实现?如果可以,该如何操作?
解决方案
当然可以实现!你需要使用Mongoose的聚合管道来完成这个需求——普通的find查询只能返回创作者级别的文档,无法直接跨文档展开、合并并排序视频数组。下面是具体的实现代码和步骤说明:
return mongoose.model('creators').aggregate([ // 第一步:展开每个创作者的videos数组,将每个视频转为独立文档 { $unwind: '$videos' }, // 第二步:按视频的date字段倒序排序(-1表示降序,最新的视频排在前面) { $sort: { 'videos.date': -1 } }, // 第三步:将所有视频合并到一个数组中 { $group: { _id: null, // 用null表示将所有文档归为同一组 videos: { $push: '$videos' } // 将每个独立的视频文档推入videos数组 } }, // 第四步:移除默认的_id字段,只保留我们需要的videos数组 { $project: { _id: 0 } } ])
代码解释:
$unwind:把每个创作者文档中的videos数组拆分成多个独立文档,每个文档仅包含一个视频的信息(同时保留创作者的其他字段,但后续我们只用到视频部分)。$sort:基于拆分后的每个视频的date字段进行降序排序,确保最新的视频排在最前面。$group:将所有拆分后的视频文档重新聚合到一个组中,并用$push把每个视频收集到videos数组里。$project:移除聚合结果中默认生成的_id字段,让最终输出仅包含videos数组,完全符合你期望的格式。
可选优化:
如果需要只查询特定创作者的视频,可以在聚合管道的最开头添加$match阶段,比如:
{ $match: { id: { $in: ['UCEOXxzW2vU0P-0THehuIIeg', 'UC726J5A0LLFRxQ0SZqr2mYQ'] } } }
这样就能过滤出指定创作者的视频,再进行后续的展开、排序和合并操作。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

