How to use $elemMatch to add elements from an array to another one

Hi,

Using a pipeline I need to modify the document :

{
    "_id": {
        "$oid": "62b5de54925ed2a48da3b6b2"
    },
    "markets": [1, 2],
    "sales": [{
        "item": "A",
        "marketsToImplant": [1, 2]
    }, {
        "item": "B",
        "marketsToImplant": [1, 3]
    }]
}

for each element in “markets” array :slight_smile:

  • create an new object with a field “market”
  • add an array “sales” to this new object, and keep the items where marketsToImplant match with the current market

to give this result :

{
    "_id": {
        "$oid": "62b5de54925ed2a48da3b6b2"
    },
    "markets": [
        {
            "market":1,
            "sales": ["A", "B"]
        },
        {
            "market":2,
            "sales": ["A"]
        }
   ]
}

I tried with $map and $elemMatch but it’s wrong

please share the exact code you tried, we may help better by knowing what you tried and how it failed. it gives us a starting point to experiment.

Hi Steeve,

Here is the code I tried

The 1st stage $set create an array duplicateMarkets extract from salePeriods.panel.marketsToImplant where each element is formated {marketId:<value of the market>}

The 2nd stage $set eliminate duplicate values and create $markets array

The 3rd stage $project reduce the size of the documents

The 4th stage $set merge the salePeriods to the $market array if the marketId matchs with the salePeriods.panel.marketsToImplant

[
{
$set: {
 duplicateMarkets: {
  $reduce: {
   input: '$salePeriods.panel.marketsToImplant',
   initialValue: [],
   'in': {
    $let: {
     vars: {
      markets: {
       $map: {
        input: '$$this',
        'in': {
         marketId: '$$this'
        }
       }
      }
     },
     'in': {
      $concatArrays: [
       '$$value',
       '$$markets'
      ]
     }
    }
   }
  }
 }
}
}, 
{
$set: {
 markets: {
  $setUnion: '$duplicateMarkets'
 }
}
}, 
{
$project: {
 salePeriods: 1,
 markets: 1
}
}, 
{
$set: {
 markets: {
  $let: {
   vars: {
    salePeriods: '$salePeriods'
   },
   'in': {
    $map: {
     input: '$markets',
     as: 'market',
     'in': {
      $let: {
       vars: {
        marketSalePeriods: {
         $filter: {
          input: '$$salePeriods',
          as: 'salePeriod',
          cond: {
           $in: [
            '$$market.marketId',
            '$$salePeriod.panel.marketsToImplant'
           ]
          }
         }
        }
       },
       'in': {
        $mergeObjects: [
         '$$market',
         {
          salePeriods: '$$marketSalePeriods'
         }
        ]
       }
      }
     }
    }
   }
  }
 }
}
}
]
1 Like

This query seems complex
Do you know a way to simplify ?