MongoDB聚合查询如何返回所有文档中均不存在的数组值
MongoDB 聚合查询:获取目标数组中未在books字段出现过的值
需求说明
给定目标数组 ['123', '456', '789'],查询所有包含books字段的文档,仅返回目标数组里从未在任意文档的books字段中出现过的元素,不需要返回匹配到的原始文档。
举个参考示例:如果123、456都存在于对应文档的books字段中,只有789从未出现,最终返回结果就是['789']。
完整聚合代码
你已经写好了初始的$match过滤阶段,补全后续聚合阶段即可,完整代码如下:
.aggregate([ { $match: { books: { $in: ['123', '456', '789'] } } }, // 将books数组拆分为单条记录,单值字段会自动按单元素数组处理 { $unwind: "$books" }, // 二次过滤,仅保留属于目标数组的books值 { $match: { books: { $in: ['123', '456', '789'] } } }, // 去重统计所有实际出现过的目标值 { $group: { _id: null, existedValues: { $addToSet: "$books" } } }, // 计算目标数组和已存在值的差集,得到从未出现过的值 { $project: { _id: 0, result: { $setDifference: [['123', '456', '789'], "$existedValues"] } } } ])
逻辑说明
- 初始
$match阶段提前过滤掉books字段完全不包含目标数组元素的文档,大幅减少后续阶段需要处理的数据量,提升查询效率 $unwind阶段拆分数组后,才能对单个book值做去重统计- 二次
$match是为了排除books字段里不属于目标数组的其他值,避免干扰后续差集计算 $group阶段用$addToSet对出现过的目标值去重,避免重复值影响结果- 最终用
$setDifference取两个集合的差集,直接得到你需要的未出现值。如果没有任何文档匹配初始条件,返回的结果就是完整的目标数组,符合预期。
内容的提问来源于stack exchange,提问作者pkdev
相关产品推荐
相关产品推荐

