如何基于数组值筛选MongoDB数据并展开嵌套数组结果
实现MongoDB数组字段筛选并扁平化结果
示例原始文档
[ { "name": "ABC", "details": [ {"color": "red", "price": 20000}, {"color": "black", "price": 22000}, {"color": "blue", "price": 21000} ] }, { "name": "XYZ", "details": [ {"color": "yellow", "price": 10000}, {"color": "black", "price": 12000}, {"color": "green", "price": 11000} ] }, { "name": "CBD", "details": [ {"color": "red", "price": 30000}, {"color": "pink", "price": 32000}, {"color": "blue", "price": 31000} ] } ]
需求
筛选出color为red和blue的数据,得到以下扁平化结果:
[ {"name": "ABC", "color": "red", "price": 20000}, {"name": "ABC", "color": "blue", "price": 21000}, {"name": "CBD", "color": "red", "price": 30000}, {"name": "CBD", "color": "blue", "price": 31000} ]
当前问题
仅能筛选出包含目标颜色的文档,但未实现扁平化结构。
解决方案
1. MongoDB 聚合查询语句
直接通过聚合管道在数据库层完成筛选和扁平化:
db.collection.aggregate([ // 初步筛选包含目标颜色的文档,减少后续处理量 { $match: { "details.color": { $in: ["red", "blue"] } } }, // 展开details数组,每个元素生成独立文档 { $unwind: "$details" }, // 过滤出仅red/blue的颜色项 { $match: { "details.color": { $in: ["red", "blue"] } } }, // 构造扁平化的根文档结构 { $replaceRoot: { newRoot: { name: "$name", color: "$details.color", price: "$details.price" } } } ])
步骤说明:
- 第一次
$match:快速过滤掉完全不包含目标颜色的文档 $unwind:将数组拆分为单条记录,为扁平化做准备- 第二次
$match:精准筛选出目标颜色的数组项 $replaceRoot:将嵌套字段提升到根级别,得到最终结构
2. JS/TS 应用层处理
如果已经从数据库获取到包含筛选后数组的文档,可通过代码在应用层扁平化:
// 假设从数据库查询到的原始结果 const dbResult = [ { "name": "ABC", "details": [ {"color": "red", "price": 20000}, {"color": "blue", "price": 21000} ] }, { "name": "CBD", "details": [ {"color": "red", "price": 30000}, {"color": "blue", "price": 31000} ] } ]; // 扁平化处理 const flattenedData = dbResult.flatMap(doc => doc.details.map(item => ({ name: doc.name, color: item.color, price: item.price })) ); console.log(flattenedData);
说明:利用flatMap遍历每个文档,结合map将数组元素与文档name组合成新对象,flatMap自动展开嵌套数组,直接得到目标结构。
内容的提问来源于stack exchange,提问作者Amar Cloud
相关产品推荐
相关产品推荐

