Danny Boris Ov
Danny Boris Ov

Reputation: 69

MongoDB query aggregation localField ObjectId string and foreign field ObjectId

My goal is to aggregate 2 collections where in one, namely the user collection, I have an array of string type objectid that represent the actual ids in the other collection, namely the images collection. im using the following code

    await dbConn()
    return User.aggregate([
       {
           $match:{_id: mongoose.Types.ObjectId(id)}
       },
       {
           $unwind:'$imgIds'
       },

       {
           $lookup:{
               from:'images',
               localField:'imgIds',
               foreignField:'_id',
               as:'imgObjs'
           }
       }
    ],(err,res)=>console.log(res))
}

so there's a match of one item in the users collection. then deconstructing the imgIds array and trying to make the connection between the two with lookup whereas localField is a string and _id is an ObjectId. The result is ImgObjs is an empty array.

Any thoughts about this one? Im using version Mongo 3.6.12

------------EDIT--------------

I found out something very strange in my server behavior. When im doing a simple findById call, my image item is an array of ObjectId. But when using aggregate, the ObjecIds become String. Anyone has any idea whats up here?

Upvotes: 0

Views: 1461

Answers (1)

abondoa
abondoa

Reputation: 1783

You need to convert your strings to object IDs (or your object IDs to string).

For Mongo version 4.0 or higher

You can use $toObjectId to do this. In your case you can add an $addFields stage after your unwind:

{
  $addFields: {
    imgIdObjId: { $toObjectId: $imgIds }
  }
}

In your lookup you will need to use that field instead of imgIds:

{
  $lookup:{
    from:'images',
    localField:'imgIdObjId',
    foreignField:'_id',
    as:'imgObjs'
  }
}

For reference checkout: https://docs.mongodb.com/manual/reference/operator/aggregation/toObjectId/

Upvotes: 0

Related Questions