Mongoose: How to filter based on both a model field and associated model fields at the same time? Mongoose: How to filter based on both a model field and associated model fields at the same time? mongoose mongoose

Mongoose: How to filter based on both a model field and associated model fields at the same time?


UPDATE based on comments: "Removed all institutions related code."

const country_name = "India";const users = await UserSchema.aggregate([    {        $match: { country: country_name }    },    {        $lookup: {            from: "profiles",            let: { profiles_id: "$profile" },            pipeline: [                {                    $match: {                        videoURL: { $nin: [undefined, null] },                        $expr: { $eq: ["$_id", "$$profiles_id"] }                    }                }            ],            as: "profiles"        }    },    { $unwind: "$profiles" }]);

Why are you maintaining users reference in profiles? Its redundant. Instead have a reference to profiles only in users collection. All the tasks that you mentioned can be performed in single query. Check this query (change it precisely to your requirement):

const country_name = "India";const institution_pattern = /^Insti/;const users = await UserSchema.aggregate([    {        $match: { country: country_name }    },    {        $lookup: {            from: "profiles",            let: { profiles_id: "$profile" },            pipeline: [                {                    $match: {                        videoURL: { $nin: [undefined, null] },                        $expr: { $eq: ["$_id", "$$profiles_id"] }                    }                },                {                    $lookup: {                        from: "institutions",                        localField: "institution",                        foreignField: "_id",                        as: "institution"                    }                },                { $unwind: "$institution" }            ],            as: "profiles"        }    },    { $unwind: "$profiles" },    {        $match: {            "profiles.institution.name": {                $regex: institution_pattern,                $options: "i"            }        }    }]);

Output

{    "_id" : ObjectId("604cb4c36b2dcb17e8b152b8"),    "profile" : ObjectId("604cb4b16b2dcb17e8b152b5"),    "country" : "India",    "profiles" : {        "_id" : ObjectId("604cb4b16b2dcb17e8b152b5"),        "institution" : {            "_id" : ObjectId("604cb49a6b2dcb17e8b152b2"),            "name" : "Institute 1"        },        "videoURL" : "http://abc1.xyz"    }}

Test data:

usres collection:

/* 1 createdAt:3/13/2021, 6:19:07 PM*/{    "_id" : ObjectId("604cb4c36b2dcb17e8b152b8"),    "profile" : ObjectId("604cb4b16b2dcb17e8b152b5"),    "country" : "India"},/* 2 createdAt:3/13/2021, 6:19:07 PM*/{    "_id" : ObjectId("604cb4c36b2dcb17e8b152b9"),    "profile" : ObjectId("604cb4b16b2dcb17e8b152b6"),    "country" : "India"},/* 3 createdAt:3/13/2021, 6:19:07 PM*/{    "_id" : ObjectId("604cb4c36b2dcb17e8b152ba"),    "profile" : ObjectId("604cb4b16b2dcb17e8b152b7"),    "country" : "U.S"}

profiles collection

/* 1 createdAt:3/13/2021, 6:18:49 PM*/{    "_id" : ObjectId("604cb4b16b2dcb17e8b152b5"),    "institution" : ObjectId("604cb49a6b2dcb17e8b152b2"),    "videoURL" : "http://abc1.xyz"},/* 2 createdAt:3/13/2021, 6:18:49 PM*/{    "_id" : ObjectId("604cb4b16b2dcb17e8b152b6"),    "institution" : ObjectId("604cb49a6b2dcb17e8b152b3")},/* 3 createdAt:3/13/2021, 6:18:49 PM*/{    "_id" : ObjectId("604cb4b16b2dcb17e8b152b7"),    "institution" : ObjectId("604cb49a6b2dcb17e8b152b4"),    "videoURL" : "http://abc3.xyz"}

institutions collection:

/* 1 createdAt:3/13/2021, 6:18:26 PM*/{    "_id" : ObjectId("604cb49a6b2dcb17e8b152b2"),    "name" : "Institute 1"},/* 2 createdAt:3/13/2021, 6:18:26 PM*/{    "_id" : ObjectId("604cb49a6b2dcb17e8b152b3"),    "name" : "Institute 2"},/* 3 createdAt:3/13/2021, 6:18:26 PM*/{    "_id" : ObjectId("604cb49a6b2dcb17e8b152b4"),    "name" : "Institute 3"}