Home > OS >  Mongoose - FindOne and Search inside and Array
Mongoose - FindOne and Search inside and Array

Time:11-20

In my users collection i'm storing inside an array a set of wishlist items as follow

{
    "_id" : ObjectId("61840f03cfd5c0b680648f2c"),
    "email" : "[email protected]",
    "wishlist" : [ 
        ObjectId("6182a45f38f323f21bec2ddc"), 
        ObjectId("61825f026d0fd99ef70380fd")
    ]
}

In my React Product page i want to check if the product has already been added to the whishlist, based on the email, and the objectID saved on the wishlist array ((i.e. 6182a45f38f323f21bec2ddc) .

Despite the effort i can not understand how to write the query using mongoose.

The best solution I came up with is

db.getCollection('users').find({
    email: "[email protected]",
    "user.wishlist" : "6182a45f38f323f21bec2ddc",
    
    }).select('wishlist').exec()

But i'm getting an empty array as a result. If the product is found i want to return the objectId of the product. How do I explicitly tell mongoose select the document matching a specific email address and then map into each element of the wishlist array in order to find the matching product?

For sake of clarity below is my user model

const userSchema = new mongoose.Schema({
    email:{
        type:String,
        required: true,
        index: true,
    },
    wishlist:[{type:ObjectId, ref:"Product"}],
    },
    {timestamps: true}
);

Thanks for your help guys!

CodePudding user response:

The problem is your query is wrong. You are trying to find into user.wishlist but in your schema the field is only wishlist.

So you need this query:

db.getCollection('users').find({
    email: "[email protected]",
    "wishlist" : "6182a45f38f323f21bec2ddc"
}).select('wishlist').exec()

Example here

Also, I think mongoose parse automatically the string to ObjectId but maybe is needed to use mongoose.Types.ObjectId() like this:

db.getCollection('users').find({
    email: "[email protected]",
    "wishlist" : mongoose.Types.ObjectId("6182a45f38f323f21bec2ddc")
}).select('wishlist').exec()

And least, if I've understood the question, you can avoid the map after the execution using projection stage like this example to get only the element which match the value.

db.getCollection('users').find({
    email: "[email protected]",
    "wishlist" : "6182a45f38f323f21bec2ddc"
},
{
  "wishlist.$": 1
}).select('wishlist').exec()
  • Related