Search code examples
mongodbmongodb-querymongodb-lookup

MongoDB multiple subqueries


I'm kinda new to no-sql databases, so I have a question on subqueries here.

Let's imagine the following structure:

Type (_id, offerId)
Offer (_id, typeId, productId)
Product (_id, subId)

I need to find all types by subId.

I have no idea on how does it work for MongoDB, in SQL I'd do something like:

select * from Type where offerId in 
  (select _id from Offer where productId in
    (select _id from Product where subId = 'test'));

For MongoDB I tried to create some kind of aggregation query, but it doesn't work:

{
  "aggregate": "Type",
  "pipeline": [
    {
      "$lookup": {
        "from": "Offer",
        "localField": "_id",
        "foreignField": "typeId",
        "as": "subOffer"
      }
    },
    {
      "$lookup": {
        "from": "Product",
        "localField": "_id",
        "foreignField": "subOffer.productId",
        "as": "subProduct"
      }
    },
    {
      "$match": {
        "subProduct.subId": "test"
      }
    },
    {
      "$unwind": "$subProduct"
    },
    {
      "$unwind": "$subOffer"
    }
  ]
}

Any suggestions here?


Solution

  • You can try,

    • $lookup on offer collection using pipeline
    • $match type id
    • $lookup on product collection using pipeline
    • $match fields subId and productId
    • $match product is not [] empty
    • $match offer is not [] empty
    • $project remove offer field
    db.type.aggregate([
      {
        $lookup: {
          from: "offer",
          let: { tid: "$_id" },
          as: "offer",
          pipeline: [
            { $match: { $expr: { $eq: ["$$tid", "$typeId"] } } },
            {
              $lookup: {
                from: "product",
                as: "product",
                let: { pid: "$productId" },
                pipeline: [
                  {
                    $match: {
                      $and: [
                        { subId: "test" },
                        { $expr: { $eq: ["$_id", "$$pid"] } }
                      ]
                    }
                  }
                ]
              }
            },
            { $match: { product: { $ne: [] } } }
          ]
        }
      },
      { $match: { offer: { $ne: [] } } },
      { $project: { offer: 0 } }
    ])
    

    Playground