求助:MongoDB中按指定格式返回变体产品的属性值关联数据
解决方案:MongoDB聚合实现属性值对应产品ID列表
针对你的需求,我们可以通过MongoDB的聚合管道来实现,下面是具体的实现步骤和代码:
核心思路
我们需要先筛选目标产品,展开属性数组,然后按属性值分组收集对应的productId,最后转换成你需要的输出格式。同时会过滤掉VariantValues集合中未定义的属性(比如示例中的Memory Components)。
聚合查询代码
db.products.aggregate([ // 1. 筛选isVariant为1的产品 { $match: { isVariant: 1 } }, // 2. 展开attributeSet数组,让每个属性单独成为一条记录 { $unwind: "$attributeSet" }, // 3. 只保留VariantValues中关注的属性(对应id为3和4的属性) { $match: { "attributeSet.id": { $in: [3, 4] } } }, // 4. 按属性值分组,收集对应的productId列表 { $group: { _id: "$attributeSet.value", productIds: { $push: "$productId" } } }, // 5. 转换为要求的格式:将productIds转成{productId: ...}的数组 { $project: { _id: 0, attributeValue: "$_id", data: { $map: { input: "$productIds", as: "pid", in: { productId: "$$pid" } } } } }, // 6. 将所有属性值的结果收集到variantValues数组中 { $group: { _id: null, variantValues: { $push: "$$ROOT" } } }, // 7. 移除不必要的_id字段 { $project: { _id: 0 } } ])
代码解释
- $match:第一步先过滤出
isVariant:1的产品,减少后续处理的数据量。 - $unwind:把每个产品的
attributeSet数组展开,这样每个属性会单独形成一条文档,方便后续按属性值分组。 - $match(第二次):根据
VariantValues集合中的属性ID(3和4),过滤掉不需要的属性(比如示例中的Memory Components)。 - $group:按属性值(
attributeSet.value)分组,用$push收集该属性值对应的所有productId。 - $project:将分组后的结果转换成你需要的格式,用
$map把productIds数组中的每个元素包装成{productId: ...}的对象。 - $group(第二次):把所有属性值的结果汇总到
variantValues数组中,符合你要求的输出结构。 - $project(第二次):移除自动生成的
_id字段,让输出更干净。
动态适配VariantValues集合
如果VariantValues集合中的属性ID是动态变化的,你可以先查询该集合获取属性ID列表,再传入聚合管道:
// 先获取VariantValues中的属性ID,转成数字数组 const variantIds = Object.keys(db.variantValues.findOne().VariantValues).map(Number); // 再执行聚合查询 db.products.aggregate([ { $match: { isVariant: 1 } }, { $unwind: "$attributeSet" }, { $match: { "attributeSet.id": { $in: variantIds } } }, // 后续步骤和上面一致... ])
输出结果
执行上述聚合后,你会得到和需求完全一致的输出:
{ "variantValues": [ { "attributeValue": "500 GB", "data": [ { "productId": 1 }, { "productId": 3 } ] }, { "attributeValue": "1 TB", "data": [ { "productId": 2 }, { "productId": 4 } ] }, { "attributeValue": "5 inch", "data": [ { "productId": 1 }, { "productId": 2 } ] }, { "attributeValue": "2.5 inch", "data": [ { "productId": 3 }, { "productId": 4 } ] } ] }
内容的提问来源于stack exchange,提问作者Vishal Kumar
相关产品推荐
相关产品推荐

