Vikas Valechha
Vikas Valechha

Reputation: 333

how to get data from second collection based on the result of first collection - mongodb

I have two collection named brands and offers. I need to write a query to display the total offers associated with the branch and in the output of the query, I also need to show the brandName based on uuid in BrandModel, both in a single query. Can it be done in a single query? If yes, then the help would be appreciated. Model for both the collections and the snapshot of expected result is give below:

BrandModel
{
    "uuid" : "1",
    "brandName" : "Siyarams",
    "addedOn" : 1511336968608,
    "contactPerson" : "Kapoor",
    "primaryContactNo" : "9999999999",
    "alternateContactNo" : "9999999999",
    "address" : "57th main",
    "landmark" : "Near KFC",
    "city" : "Mumbai",
    "brandStatus" : 3,
    "lastEdited" : 1511347444340
}

OfferModel
{
    "offerId" : "2",
    "brandUuid" : ["1"],
    "storeUuid" : ["1", "2", "3", "4"],
    "startTime" : 1427985798581,
    "endTime" : 1489846620149,
    "offerDesc" : "Nunc nisl.",
    "criteria" : "Nulla ac enim.",
    "minShoppingAmount" : 72,
    "maxShoppingAmount" : 13,
    "minCashbackAmount" : 166,
    "maxCashbackAmount" : 33,
    "offerStatus" : 2,
    "addedOn" : 1464960534465
}

Expected result

{
  "totalCount": 6,
  "offerList": [
    {
      "offerId": "2",
      "startTime": 1458414172009,
      "endTime": 1432239091529,
      "offerStatus": 2,
      "brandUuid": "1",
      "brandName": "Reebok",
      "storeCount": 4
    },
    {
      "offerId": "3",
      "startTime": 1502408506014,
      "endTime": 1418943623940,
      "offerStatus": 2,
      "brandUuid": "44",
      "brandName": "Adidas",
      "storeCount": 3
    },
    {
      "offerId": "4",
      "startTime": 1460451658862,
      "endTime": 1431555556723,
      "offerStatus": 1,
      "brandUuid": "30",
      "brandName": "Levis",
      "storeCount": 3
    },
    {
      "offerId": "5",
      "startTime": 1477083967093,
      "endTime": 1433758573895,
      "offerStatus": 1,
      "brandUuid": "32",
      "brandName": "Caterpilar",
      "storeCount": 2
    }
  ]
}

EDITED: I got the result based on @Raul's answer and now my query looks like:

db.coll.aggregate([
  {
    $facet: {
      totalCount: [
        {
          $count: "count"
        }
      ],
      offerList: [
        {
          $match: {
            offerStatus: 2
          }
        },
        {
          $unwind: "$brandUuid"
        },
        {
          $project: {
            _id: 0,
            offerId: 1,
            brandUuid: 1,
            storeCount: {
              $size: "$storeUuid"
            },
            startTime: 1,
            endTime: 1,
            offerStatus: 1
          }
        },
        {
          $lookup: {
            from: "brands",
            localField: "brandUuid",
            foreignField: "brandUuid",
            as: "brand"
          }
        },
        {
          $addFields: {
            brand: {
              $arrayElemAt: [
                "$brand.brandName",
                0
              ]
            }
          }
        }
      ]
    }
  },
  {
    $addFields: {
      totalCount: {
        $arrayElemAt: [
          "$totalCount.count",
          0
        ]
      }
    }
  }
])

Upvotes: 0

Views: 300

Answers (1)

Raul Rueda
Raul Rueda

Reputation: 750

This could help you, using aggregate in one query. Just check if you typed correctly or why you have a brandUuid as array? This means your offer could have multiple brands, in that case consult $unwind stage.

db.BrandModel.aggregate([
   {
        $lookup: {
            from: "OfferModel",
            localField: "uuid",
            foreignField: "brandUuid",
            as: "offerList"
        }
    } 
]);

Update (Unwind from the collection that has the array):

 db.OfferModel.aggregate([
   {
        $unwind: "$brandUuid"
   },
   {
        $lookup: {
            from: "BrandModel",
            localField: "brandUuid",
            foreignField: "uuid",
            as: "brand"
        }
   },
   {
        $group : { _id : "$brand" }
   }
]);

Upvotes: 1

Related Questions