parveen
parveen

Reputation: 577

MongoDB conditional aggregation with unwind

I have db collection like:

{
  "_id" : "af5c00e4-d3a8-419d-8793-c0cf328802ec",
    "collaborators" : [
        {
            "_id" : "9bd2eee8-bf6c-4c6f-bab7-d2d175aed807",
            "origin" : [
                {
                    "originId" : "123"
                }
            ],
            "firstName" : "Parveen",
            "lastName" : "Vendor",
            "email" : "[email protected]"
        },
        {
            "_id" : "234324-bf6c-4c6f-bab7-d2d175aed807",
            "origin" : [
                {
                    "originId" : "1234"
                }
            ],
            "firstName" : "Parveen123",
            "lastName" : "34",
            "email" : "[email protected]"
        }
    ],
    "orders" : [
        {
            "totalAmount" : 10,
            "collaborators" : [
                {
                    "origin" : [
                        {
                            "originId" : "123",
                        }
                    ],
                    "type" : "Supplier"
                },
                {
                    "origin" : [
                        {
                            "originId" : "1233",
                        }
                    ],
                    "type" : "Supplier"
                }
            ]
        }
    ]
}

Want to replace data in orders (array) collaborators(array) with

**collaborators(array) ** data if matches originId of both

Expected output

{
  "_id" : "af5c00e4-d3a8-419d-8793-c0cf328802ec",
    "collaborators" : [
        {
            "_id" : "9bd2eee8-bf6c-4c6f-bab7-d2d175aed807",
            "origin" : [
                {
                    "originId" : "123"
                }
            ],
            "firstName" : "Parveen",
            "lastName" : "Vendor",
            "email" : "[email protected]"
        },
        {
            "_id" : "234324-bf6c-4c6f-bab7-d2d175aed807",
            "origin" : [
                {
                    "originId" : "1234"
                }
            ],
            "firstName" : "Parveen123",
            "lastName" : "34",
            "email" : "[email protected]"
        }
    ],
    "orders" : [
        {
            "totalAmount" : 10,
            "collaborators" : [
                {
                    "_id" : "9bd2eee8-bf6c-4c6f-bab7-d2d175aed807",
                    "origin" : [
                        {
                            "originId" : "123"
                        }
                    ],
                    "firstName" : "Parveen",
                    "lastName" : "Vendor",
                    "email" : "[email protected]"
                },
                {
                    "origin" : [
                        {
                            "originId" : "1233",
                        }
                    ],
                    "type" : "Supplier"
                }
            ]
        }
    ]
}

One collection record can have multiple collaborators , same as order can have multiple collaborators. Need to replace only where originId matches

Upvotes: 0

Views: 547

Answers (1)

nimrod serok
nimrod serok

Reputation: 16033

One option is:

  1. Use $map, $mergeObjects and $filter to add a new key to each item of orders.collaborators with the matching item from collaborators if exists.
  2. choose the new key if it contains data or the original key, if not.
db.collection.aggregate([
  {$set: {
      ordersCollaborators: {
        $map: {
          input: {$first: "$orders.collaborators"},
          in: {$mergeObjects: [
              {original: "$$this"},
              {new: {
                  $filter: {
                    input: "$collaborators",
                    as: "i",
                    cond: {
                      $eq: [
                        {$first: "$$i.origin.originId"},
                        {$first: "$$this.origin.originId"}
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {$set: {
      orders: [
        {totalAmount: {$first: "$orders.totalAmount"},
          collaborators: {
            $map: {
              input: "$ordersCollaborators",
              in: {
                $cond: [
                  {$eq: [{$size: "$$this.new"}, 0]},
                  "$$this.original",
                  "$$this.new"
                ]
              }
            }
          }
        }
      ],
      ordersCollaborators: "$$REMOVE"
    }
  }
])

See how it works on the playground example

Upvotes: 1

Related Questions