Getting null array as result in mongodb aggregate pipeline

Issue

Here is my code, I have two collections called cart and product, First I want to take the id of the product from the cart and then from the product collection get the product details

collection cart

{
    "_id" : ObjectId("62f8086e29c549f34ab89df7"),
    "user" : ObjectId("62f3f8600e93c17d1c25c2ed"),
    "product" : [
        ObjectId("62f391b9482a375c4f83de8e"),
        ObjectId("62f39121482a375c4f83de8d"),
        ObjectId("62f39200482a375c4f83de8f")
    ]
}

collection product

{
    "_id" : ObjectId("62f39121482a375c4f83de8d"),
    "name" : "iphone 15",
    "category" : "mobiles",
    "price" : "125",
    "description" : "fastest iphone"
}
{
    "_id" : ObjectId("62f391b9482a375c4f83de8e"),
    "name" : "OnePlus Nord",
    "category" : "mobile",
    "price" : "40000",
    "description" : "budget phone of OnePlus"
}
{
    "_id" : ObjectId("62f39200482a375c4f83de8f"),
    "name" : "Samsung M33",
    "category" : "mobile",
    "price" : "25000",
    "description" : "mid range mobile"
}

Here is the function for getting the details

getcartProducts:(userId)=>{
        return new Promise(async(resolve,reject)=>{
            let cartItem=await db.get().collection(collection.CART_COLLECTION).aggregate([
                {
                    "$match":{user:objectId(userId)}
                   
                },
                {
                    "$lookup":{
                        "from":collection.PRODUCT_COLLECTIONS,
                        "let":{"prodList":'$product'},
                    
                        pipeline:[

                            {
                                
                                "$match":{ "$expr":{ "$in":["_id","$$prodList"],
                                    },
                                },
                            },
                        ],
                        "as":"cartItems"
                    
                    }
                }
            ]
            ).toArray()
            resolve(cartItem) 
          
        })

    }

Finally the function is called

router.get('/cart',verifyLogin,async (req,res)=>{
    let products=await userHelpers.getcartProducts(req.session.user._id)
    console.log(products)
    res.render('user/cart')
  })

The output is: Showing null array in cartItems: []

 [
  {
    _id: new ObjectId("62f8086e29c549f34ab89df7"),
    user: new ObjectId("62f3f8600e93c17d1c25c2ed"),
    product: [
      new ObjectId("62f391b9482a375c4f83de8e"),
      new ObjectId("62f39121482a375c4f83de8d"),
      new ObjectId("62f39200482a375c4f83de8f"),
      new ObjectId("62f39121482a375c4f83de8d")
    ],
    cartItems: []
  }
]

Solution

Use $_id instead of _id in $in operator. Mongo Playground

// This is the raw query
db.carts.aggregate([
  {
    "$match": {
      "user": ObjectId("62f3f8600e93c17d1c25c2ed")
    }
  },
  {
    "$lookup": {
      "from": "products",
      "as": "cartItems",
      "let": {
        "prodList": "$product"
      },
      pipeline: [
        {
          "$match": {
            "$expr": {
              "$in": [
                "$_id",  // note the change here, use $ for matching field in lookup collection
                "$$prodList" // use $$ for matching variable
              ],
              
            },
            
          },
          
        },
        
      ],
      
    }
  }
])

Change the following line in your example code:

"$match":{ "$expr":{ "$in":["_id","$$prodList"],

To:

"$match":{ "$expr":{ "$in":["$_id","$$prodList"],

This aggregation pipeline cane be simplified to: Mongo Playground

[
  {
    "$match": {
      "user": ObjectId("62f3f8600e93c17d1c25c2ed")
    }
  },
  {
    "$lookup": {
      "from": "products",
      "as": "cartItems",
      "localField": "product",
      "foreignField": "_id"
    }
  }
]

Answered By – Ramit Mittal

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published