MongoDB聚合:多条件过滤fruits集合的variants子文档
MongoDB聚合实现方案
完整聚合管道
const available_prop_uids = [1,4,5]; db.fruits.aggregate([ // 过滤掉variants.props为空或不存在的文档 { $match: { "variants.props": { $exists: true, $ne: [] } } }, // 计算当前文档所有variants中props.grade的全局最大值 { $addFields: { maxGrade: { $max: { $map: { input: "$variants", as: "variant", in: { $max: "$$variant.props.grade" } } } } } }, // 第一步过滤:保留包含最高grade的variant { $addFields: { variants: { $filter: { input: "$variants", as: "variant", cond: { $in: ["$maxGrade", "$$variant.props.grade"] } } } } }, // 第二步过滤:仅保留所有props.uid都在可用列表中的variant { $addFields: { variants: { $filter: { input: "$variants", as: "variant", cond: { $eq: [ { $size: "$$variant.props" }, { $size: { $filter: { input: "$$variant.props", as: "prop", cond: { $in: ["$$prop.uid", available_prop_uids] } } } } ] } } } } }, // 清理临时字段 { $project: { maxGrade: 0 } } ])
阶段详解
- $match阶段
先过滤掉variants.props为空或不存在的文档,确保后续操作只处理符合基础条件的文档。 - 计算全局最高grade
使用$map遍历每个variant,提取其props中的最高grade,再用$max得到整个文档所有variant的最高grade,存入临时字段maxGrade。 - 第一步过滤(保留含最高grade的variant)
用$filter遍历variants数组,仅保留那些props中包含maxGrade值的variant,通过$in判断maxGrade是否存在于当前variant的props.grade数组中。 - 第二步过滤(保留所有uid合法的variant)
再次用$filter处理第一步后的variants数组:对每个variant,过滤出其中uid在available_prop_uids中的props,比较过滤前后的props数组长度。如果长度相等,说明该variant的所有props的uid都合法,予以保留。 - $project阶段
移除临时字段maxGrade,得到最终结果结构。
内容的提问来源于stack exchange,提问作者Lucien Chardon
相关产品推荐
相关产品推荐

