Priyank lohan
Priyank lohan

Reputation: 483

Mongodb apply condition on $lookup fetched data

I am having data from two different collections on which I am applying $lookup with $match which is working fine. What I am trying to do is on lookup's result I am applying $match again which is having some conditions. Here is the collection of User on which I am applying lookup. Users collection :-

{
"_id": {
    "$oid": "5b714631faaae220d7cc07cf"
},
"name": "abc",
"surname": "xyz",
"email": "[email protected]",
"hotel_data": [
    {
        "location": {
            "type": "Point",
            "coordinates": [
                30.7052881,
                76.84470799999997
            ]
        },
        "_id": {
            "$oid": "5b7fb8559849fd485dc47240"
        },
        "status": true,
       "activityname": "Sparrow",
    },
    {   
        "location": {
            "type": "Point",
            "coordinates": [
                30.733315,
                76.779419
            ]
        },
        "_id": {
            "$oid": "5b7f9ecb9960053dac7ce6f1"
        },
        "status": true,
        "activityname": "Raj Hotel",
       },

] 
}

and this is my availabilities collection on which I am applying $lookup with $match.

{
"_id": {
    "$oid": "5b867766d63c4e2cdd5534d2"
},
"businessid": {
    "$oid": "5b7fb8559849fd485dc47240"
},
"userid": {
    "$oid": "5b714631faaae220d7cc07cf"
},
"hotel_filters": [
    {
        "_id": {
            "$oid": "5b867766d63c4e2cdd5534d3"
        },
        "hotelservice": [
            {
                "service_id": "5b472fff25556c3f02a875aa",
                "service_name": "Pool",
                "_id": {
                    "$oid": "5b867767d63c4e2cdd5534d7"
                }
            },
            {
                "service_id": "5b472fdb25556c3f02a875a9",
                "service_name": "AIR",
                "_id": {
                    "$oid": "5b867767d63c4e2cdd5534d8"
                }
            }
        ],
        "location_type": [
            {
                "locationtype_id": "5b18f4d08c63f42019763b12",
                "locationtype_name": "Scenic View",
                "_id": {
                    "$oid": "5b867767d63c4e2cdd5534d5"
                }
            },
            {
                "locationtype_id": "5b18f4e38c63f42019763b13",
                "locationtype_name": "Central",
                "_id": {
                    "$oid": "5b867767d63c4e2cdd5534d6"
                }
            }
        ],
        "hotel_type": [
            {
                "hoteltype_id": "5b081452edefe23318834a28",
                "hoteltype_name": "3 Star",
                "_id": {
                    "$oid": "5b867767d63c4e2cdd5534d4"
                }
            }
        ]
    }
]
}

and what I am trying to do is- after $lookup I only want those availabilities data which are having "hotelservice.service_id" and "location_type.locationtype_id" that I will pass. And I have tried this by applying this query to it(In this query I have only applied "hotelservice.service_id" but later on I also want to apply query with $and on "location_type.locationtype_id").

User.aggregate([
        {
            $match:{
                "hotel_data.location": {
                    "$geoWithin": {
                        "$centerSphere": [
                            [30.7052881, 76.84470799999997], 50/ 6371
                        ]
                    }
                }
            }
        },{
            "$unwind": "$hotel_data"
        },
        {
            $match:{
                "hotel_data.location": {
                    "$geoWithin": {
                        "$centerSphere": [
                            [30.7052881, 76.84470799999997], 50/ 6371
                        ]
                    }
                }
            }
        },

        {
            $lookup: {
                from: "availabilities",
                localField: "hotel_data._id",
                foreignField: "businessid",
                as: "availabilitiesdata"
            }
        },
        {$match:{$and: [{"availabilitiesdata.hotel_filters.hotelservice.service_id":{$in:[5b472fb725556c3f02a875a8]}}]}}
    ], function(err, data) {
        if (err) {
            return res.send({data: err, status: false,  msg:"No Hotel Found" });
        }else{ 
            return res.send({status: true,  msg:"Hotel Found", data:data });
        }
    });

This query gives me result as follow.

{
"status": true,
"msg": "Hotel Found",
"data": [
    {
        "_id": "5b714631faaae220d7cc07cf",
        "name": "abc",
        "surname": "xyz",
        "email": "[email protected]",
        "hotel_data": {
            "location": {
                "type": "Point",
                "coordinates": [
                    30.7052881,
                    76.84470799999997
                ]
            },
            "_id": "5b7fb8559849fd485dc47240",
            "status": true,
            "activityname": "Sparrow",

        },
        "availabilitiesdata": [
            {
                "_id": "5b864fe68ab0b71f4f28021e",
               "businessid": "5b7fb8559849fd485dc47240",
                "userid": "5b714631faaae220d7cc07cf",
                "hotel_filters": [
                    {
                        "_id": "5b864fe78ab0b71f4f28021f",
                        "hotelservice": [
                            {
                                "service_id": "5b472fb725556c3f02a875a8",
                                "service_name": "Parking",
                                "_id": "5b864fe78ab0b71f4f280223"
                            },
                            {
                                "service_id": "5b472fff25556c3f02a875aa",
                                "service_name": "Pool",
                                "_id": "5b864fe78ab0b71f4f280224"
                            }
                        ],
                        "location_type": [
                            {
                                "locationtype_id": "5b18f4798c63f42019763b11",
                                "locationtype_name": "Quiet",
                                "_id": "5b864fe78ab0b71f4f280221"
                            },
                            {
                                "locationtype_id": "5b18f4e38c63f42019763b13",
                                "locationtype_name": "Central",
                                "_id": "5b864fe78ab0b71f4f280222"
                            }
                        ],
                        "hotel_type": [
                            {
                                "hoteltype_id": "5b0813e2edefe23318834a27",
                                "hoteltype_name": "5 Star",
                                "_id": "5b864fe78ab0b71f4f280220"
                            }
                        ]
                    }
                ]
            },
            {
                "_id": "5b867766d63c4e2cdd5534d2",
                "businessid": "5b7fb8559849fd485dc47240",
                "userid": "5b714631faaae220d7cc07cf",
                "hotel_filters": [
                    {
                        "_id": "5b867766d63c4e2cdd5534d3",
                        "hotelservice": [
                            {
                                "service_id": "5b472fff25556c3f02a875aa",
                                "service_name": "Pool",
                                "_id": "5b867767d63c4e2cdd5534d7"
                            },
                            {
                                "service_id": "5b472fdb25556c3f02a875a9",
                                "service_name": "AIR",
                                "_id": "5b867767d63c4e2cdd5534d8"
                            }
                        ],
                        "location_type": [
                            {
                                "locationtype_id": "5b18f4d08c63f42019763b12",
                                "locationtype_name": "Scenic View",
                                "_id": "5b867767d63c4e2cdd5534d5"
                            },
                            {
                                "locationtype_id": "5b18f4e38c63f42019763b13",
                                "locationtype_name": "Central",
                                "_id": "5b867767d63c4e2cdd5534d6"
                            }
                        ],
                        "hotel_type": [
                            {
                                "hoteltype_id": "5b081452edefe23318834a28",
                                "hoteltype_name": "3 Star",
                                "_id": "5b867767d63c4e2cdd5534d4"
                            }
                        ]
                    }
                ]
            }
        ]
    }
]}

but what I want is something like this.

{
"status": true,
"msg": "Hotel Found",
"data": [
    {
        "_id": "5b714631faaae220d7cc07cf",
        "name": "abc",
        "surname": "xyz",
        "email": "[email protected]",
        "hotel_data": {
            "location": {
                "type": "Point",
                "coordinates": [
                    30.7052881,
                    76.84470799999997
                ]
            },
            "_id": "5b7fb8559849fd485dc47240",
            "status": true,
            "activityname": "Sparrow",

        },
        "availabilitiesdata": [
            {
                "_id": "5b864fe68ab0b71f4f28021e",
               "businessid": "5b7fb8559849fd485dc47240",
                "userid": "5b714631faaae220d7cc07cf",
                "hotel_filters": [
                    {
                        "_id": "5b864fe78ab0b71f4f28021f",
                        "hotelservice": [
                            {
                                "service_id": "5b472fb725556c3f02a875a8",
                                "service_name": "Parking",
                                "_id": "5b864fe78ab0b71f4f280223"
                            },
                            {
                                "service_id": "5b472fff25556c3f02a875aa",
                                "service_name": "Pool",
                                "_id": "5b864fe78ab0b71f4f280224"
                            }
                        ],
                        "location_type": [
                            {
                                "locationtype_id": "5b18f4798c63f42019763b11",
                                "locationtype_name": "Quiet",
                                "_id": "5b864fe78ab0b71f4f280221"
                            },
                            {
                                "locationtype_id": "5b18f4e38c63f42019763b13",
                                "locationtype_name": "Central",
                                "_id": "5b864fe78ab0b71f4f280222"
                            }
                        ],
                        "hotel_type": [
                            {
                                "hoteltype_id": "5b0813e2edefe23318834a27",
                                "hoteltype_name": "5 Star",
                                "_id": "5b864fe78ab0b71f4f280220"
                            }
                        ]
                    }
                ]
            }
        ]
    }
]}  

I want only those availabilities which match the condition on my $lookup availability data. can someone help me out.

Upvotes: 0

Views: 507

Answers (1)

s7vr
s7vr

Reputation: 75914

You can use $lookup pipeline variant to apply the $match inside the joined collection in 3.6

Something like ( replace $lookup & $match stage with below lookup pipeline )

{"$lookup":{
  "from":"availabilities",
  "let":{"hotel_data_id":"$hotel_data._id"},
  "pipeline":[
    {"$match":{
      "hotel_filters.hotelservice.service_id":{"$in":["5b472fb725556c3f02a875a8"]},
      "hotel_filters.location_type.locationtype_id":{"$in":["5b18f4798c63f42019763b11"]},
      "$expr":{"$eq":["$$hotel_data_id","$businessid"]}
    }}
  ],
  "as":"availabilitiesdata"
}}

Upvotes: 1

Related Questions