Loading...
Loading...
When running an aggregation pipeline that performs two $lookup + $unwind stages, followed by a $project, root-level fields are silently dropped from the output. No error is thrown. The issue is triggered specifically when: The root document has a type field (string) One or both looked-up collections also have a type field (string or object) One of the root documents contains a products array where each element has a nested type field that is an object (not a string) The field venue (and potentially others) is consistently dropped from the $project output despite being present in the document at that stage, confirmed by running the same pipeline without the $project stage.
js {{// Collection: Events (root document structure){type: "PURCHASE_CREATED", // stringcontact_id: "uuid-1",transaction: { id: "txn-uuid-1" } ,venue: { // THIS FIELD GETS DROPPEDid: "venue-uuid-1",name: "Some Venue"} ,products: [{type: { // nested object type — triggers the bugid: "product-type-uuid",name: "Generic Products"}}]}// Collection: RewardEvents {id: "txn-uuid-1", // joins on transaction.idtype: "REWARD_EVENT", // string — conflict with root typetotal_award: Decimal128("3.00"),total_spend: Decimal128("0.00"),total_open_spend: Decimal128("0.00"),total_commerce_spend: Decimal128("0.00"),total_crm_wallet_spend: Decimal128("0.00")} // Collection: ContactProfiles{contact_id: "uuid-1", // joins on contact_idtype: "CONTACT_UPDATED", // string — conflict with root typeprofile: {id: "uuid-1",name: "Some Name",type: "PERSON" // nested string type}}}} Pipeline: js {{[{ $match: { "transaction.id": "txn-uuid-1" } },{$lookup: {from: "RewardEvents",localField: "transaction.id",foreignField: "id",as: "RewardEvents"}}, { $unwind: "$RewardEvents" } ,{$lookup: {from: "ContactProfiles",localField: "contact_id",foreignField: "contact_id",as: "ContactProfiles"}}, { $unwind: "$ContactProfiles" } ,{$project: {type: 1,contact_id: 1,merchant: 1,submited_date: 1,transaction: 1,venue: 1, // silently dropped"RewardEvents.total_award": 1,"RewardEvents.total_spend": 1,"RewardEvents.total_open_spend": 1,"RewardEvents.total_commerce_spend": 1,"RewardEvents.total_crm_wallet_spend": 1,"ContactProfiles.profile": 1,_id: 0}}]}} Expected Result: js {{{type: "PURCHASE_CREATED",contact_id: "uuid-1",venue: { id: "venue-uuid-1", name: "Some Venue" } , // presenttransaction: { ... },RewardEvents: { total_award: 3.00, ... },ContactProfiles: { profile: { ... } }}}} Actual Result: js {{{type: "PURCHASE_CREATED",contact_id: "uuid-1",// venue is completely absent — no error throwntransaction: { ... },RewardEvents: { total_award: 3.00, ... },ContactProfiles: { profile: { ... } }}}} Additional Observations: The bug is silent — no error or warning is produced venue is confirmed present in the document immediately before $project (verified by removing $project from the pipeline) Replacing $project with $unset (inverse approach) correctly returns venue The bug appears to be triggered by the combination of: type field existing at root level, inside RewardEvents, inside ContactProfiles, AND as a nested object inside a products array element Projecting nested lookup fields using dot notation (e.g. "RewardEvents.total_award": 1) in the same $project as root-level fields Tried all of the following without success: explicit "$venue" expression syntax, $addFields before $project, removing conflicting type fields via $$REMOVE before projecting Workaround: Use $unset to remove unwanted fields instead of $project to include desired fields.
Click on a version to see all relevant bugs
MongoDB Integration
Learn more about where this data comes from
Bug Scrub Advisor
Streamline upgrades with automated vendor bug scrubs
BugZero Enterprise
Wish you caught this bug sooner? Get proactive today.