MongoDB中$merge仅保存单条文档而非全部结果的问题排查与解决
解决MongoDB $merge仅保存单条文档的问题
你猜的完全没错!问题的根源就是两条输出文档的_id完全相同——$merge默认会以_id作为匹配键,当第二条文档写入时,因为_id与已存在的文档重复,默认会执行替换操作(whenMatched: "replace"),最终就只剩下最后一条文档了。
下面提供几种可行的解决方案,帮你用$merge保存所有聚合结果:
方案1:为每个文档生成唯一的新_id
这是最直接的方法,通过在聚合管道中为每条输出文档生成全新的唯一_id,让$merge将它们视为独立的新文档全部插入。
修改后的完整聚合管道:
db.orders.aggregate([ { '$match': { 'date': ISODate("2020-02-11T18:30:00Z") }}, { '$unwind': { 'path': '$orders' }}, { $lookup: { from: 'retailprice', let: { productCode: '$orders.productCode' }, pipeline: [ { $match: { frequency: 'FR', $expr: { $eq: ["$productCode", "$$productCode"] } } } ], as: 'retailprices' } }, { '$unwind': '$retailprices' }, // 修正了原管道中的笔误(原写法是$retailprice) { $lookup: { from: 'discounts', let: { productCode: '$orders.productCode' }, pipeline: [ { $match: { frequency: 'FR', $expr: { $eq: ["$productCode", "$$productCode"] } } } ], as: 'discounts' }}, { '$unwind': '$discounts' }, { '$project':{ 'productCode':'$orders.productCode', 'vendorId':'$vendorId', 'dealerId':'$dealerId', 'quantity':'$orders.quantity' } }, { $addFields: { _id: { $objectId: "" } } }, // 为每条文档生成全新的唯一ObjectId {'$merge':'test'} ]).pretty()
解释:$objectId: ""是MongoDB 4.0+支持的语法,会自动为每条文档生成一个独一无二的_id,这样$merge处理时不会有冲突,所有文档都会被插入到test集合中。
方案2:自定义$merge的匹配规则
如果你的业务场景中,productCode+vendorId+dealerId可以作为唯一标识(即同一商品、供应商、经销商的记录不会重复),可以通过指定$merge的on参数来替换默认的_id匹配逻辑,同时自定义重复时的处理行为。
示例1:遇到重复时保留原有文档
// 替换原管道中的{'$merge':'test'}为以下内容 {'$merge': { into: 'test', on: ['productCode', 'vendorId', 'dealerId'], // 用组合字段作为匹配键 whenMatched: 'keepExisting', // 匹配到重复文档时保留原有内容 whenNotMatched: 'insert' // 未匹配到则插入新文档 }}
示例2:遇到重复时累加数量
如果需要对重复记录的quantity进行累加,可以自定义whenMatched的合并逻辑:
{'$merge': { into: 'test', on: ['productCode', 'vendorId', 'dealerId'], whenMatched: { $set: { quantity: { $add: ["$$existing.quantity", "$$new.quantity"] } } }, // 累加现有文档和新文档的quantity whenNotMatched: 'insert' }}
额外注意点
原管道中有一个笔误:{ '$unwind': '$retailprice' }应该改为{ '$unwind': '$retailprices' }(因为$lookup的as参数指定的是retailprices),这个错误会导致管道执行失败,需要先修正。
内容的提问来源于stack exchange,提问作者sachin.pandey
相关产品推荐
相关产品推荐

