MongoDB中如何将aggregate聚合结果用作find查询的过滤条件?
MongoDB查询指定时间区间销量最差流派的Top10专辑实现方案
方法1:分两次查询(逻辑简单,适合调试)
先运行你现有的聚合管道拿到销量最低的流派,再用该流派作为过滤条件查询Top10专辑,Mongo Shell示例代码如下:
- 执行原聚合存储结果
// 执行聚合得到销量最低的流派结果 const worstGenreRes = BDA1.album.aggregate([ { $addFields: { release_date: { $toDate: "$release_date" }, sales_amount: { $convert: { input: "$sales_amount", to: "int", onError: 0 } } } }, { $match: { "release_date": { $gte: new ISODate("2009-01-01"), $lt: new ISODate("2021-01-01") } } }, { $unwind: "$band.band_genre" }, { $group: { _id: "$band.band_genre", total: { $sum: "$sales_amount" } } }, { $sort: { total: 1 } }, { $limit: 1 } ]).toArray()[0];
- 用拿到的流派过滤查询Top10专辑
BDA1.album.aggregate([ { $addFields: { release_date: { $toDate: "$release_date" }, sales_amount: { $convert: { input: "$sales_amount", to: "int", onError: 0 } } } }, { $match: { release_date: { $gte: ISODate("2009-01-01"), $lt: ISODate("2021-01-01") }, "band.band_genre": worstGenreRes._id } }, { $sort: { sales_amount: -1 } }, { $limit: 10 } ])
方法2:单聚合管道一次性查询(无需多次请求数据库)
直接通过$facet算子在同一个管道内完成流派计算和专辑过滤,代码如下:
BDA1.album.aggregate([ // 统一转换字段类型 { $addFields: { release_date: { $toDate: "$release_date" }, sales_amount: { $convert: { input: "$sales_amount", to: "int", onError: 0 } } } }, // 过滤指定时间区间的专辑 { $match: { release_date: { $gte: ISODate("2009-01-01"), $lt: ISODate("2021-01-01") } } }, // 分分支同时执行两个计算逻辑 { $facet: { // 分支1:计算销量最低的流派 calcWorstGenre: [ { $unwind: "$band.band_genre" }, { $group: { _id: "$band.band_genre", totalSales: { $sum: "$sales_amount" } } }, { $sort: { totalSales: 1 } }, { $limit: 1 } ], // 分支2:保留所有符合时间条件的原始专辑数据 validAlbums: [] } }, // 提取最低流派值 { $addFields: { worstGenre: { $arrayElemAt: ["$calcWorstGenre._id", 0] } } }, // 展开所有待过滤的专辑 { $unwind: "$validAlbums" }, // 过滤匹配流派的专辑 { $match: { $expr: { $in: ["$worstGenre", "$validAlbums.band.band_genre"] } } }, // 按销量倒序取Top10 { $sort: { "validAlbums.sales_amount": -1 } }, { $limit: 10 }, // 格式化输出专辑原始字段 { $replaceRoot: { newRoot: "$validAlbums" } } ])
注意事项
- 如果单张专辑仅归属一个流派,可以将匹配逻辑中的
$in替换为$eq,查询效率更高 $convert的onError参数用于处理字段格式异常的脏数据,可根据实际业务需求调整- 数据量较大时,建议给
release_date、band.band_genre字段添加索引提升查询性能
内容的提问来源于stack exchange,提问作者PedroSPSantos
相关产品推荐
相关产品推荐

