Search code examples
arraysmongodbupdatesaggregation

MONGODB updateMany using aggregation pipeline and $lookups


I have to update the column "AcquireMerchant.Gateway" from Merchants collection but to get the exact amount of records that I have to update it needs to do two lookups with Banks collection and Institution collection.

This is the query that im working on but doesnt work.

The problem is when it execute the forEach I got this error "cannot compare to undefined". The aggregation works perfect

db.getCollection("Merchants_INFRADB1230").aggregate( 
[
  {
    "$project": {
      "Merchants_INFRADB1230": "$$ROOT",
      "_id": 0
    }
  },
  {
    "$lookup": {
      "as": "Bancos",
      "foreignField": "_id",
      "from": "Bancos",
      "localField": "Merchants_INFRADB1230.SellingBankId"
    }
  },
  {
    "$unwind": {
      "path": "$Bancos",
      "preserveNullAndEmptyArrays": true
    }
  },
  {
    "$lookup": {
      "as": "Instituciones",
      "foreignField": "_id",
      "from": "Instituciones",
      "localField": "Bancos.InstitucionesId"
    }
  },
  {
    "$unwind": {
      "path": "$Instituciones",
      "preserveNullAndEmptyArrays": true
    }
  },
  {
    "$match": {
      "Instituciones.GlobalId": "4fb8bc86af95",
      "Merchants_INFRADB1230.AcquireMerchant.Gateway": "Update1"
    }
  },
  {
    "$project": {
      "Instituciones.GlobalId": 1,
      "Merchants_INFRADB1230.AcquireMerchant.Gateway": 1,
      "Merchants_INFRADB1230.MID": 1
    }
  }
]).forEach(doc => db.Merchants_INFRADB1230.updateMany(
       { _id: doc._id },
       { $set: { "Merchants_INFRADB1230.AcquireMerchant.Gateway": "Update2"}}));


Solution

  • The aggregation returns documents with 3 fields (you explicitly removed _id):

    "Institutions.GlobalId"
    "Merchants_INFRADB1230.AcquireMerchant.Gateway"
    "Merchants_INFRADB1230.MID"
    

    So in the forEach, the doc object will have only those fields, and doc._id will be undefined, which would make the filter {_id:doc._id} not match anything, if it were allowed to be undefined.

    The field "Merchants_INFRADB1230" was created in the aggregation, and so doesn't exist in the documents in the collection, so the update operation should probably be referring to the field as it exists in those documents:

    { $set: { "AcquireMerchant.Gateway": "Update2"}}