How to apply condition on $lookup result in mongoDB?

て烟熏妆下的殇ゞ 提交于 2019-12-05 03:56:22

You can't use "$match" with a object method after "$lookup", because return value of "$lookup" are array values. You better add "$unwind" function after the look up then group it.

Example Query

 db
.album
.aggregate([
    {
        $lookup:{
            from:"photo",
            localField:"_id",
            foreignField:"album_id",
            as:"photo"
        }
     },
    {
        preserveNullAndEmptyArrays : true,
        path : "$photo"
    },
    {
        $match:{
            "photo.flag": 1
        }
     },
     {
        $group : {
            _id : {
                id : "$_id",
                album_name: "$album_name",
                album_description: "$album_description",
                emoji_id: "$emoji_id"
            },
            photo: {
                $push : "$photo"
            }
        }
     }
    {
         $lookup:{
            from:"emoji",
            localField:"_id.album_emoji",
            foreignField:"_id",
            as:"emoji"
         }
    },
    {
         $project:{
            album_name:"$album_name",
            album_description:"$album_description",
            emoji:"$emoji",
            photo:"$photo",
            total_photos: {$size: "$photo"}
         }
    }
])

Or use "$filter".

db
.album
.aggregate([
    {
        $lookup:{
            from:"photo",
            localField:"_id",
            foreignField:"album_id",
            as:"photo"
        }
     },
    {
        $project: {
            id : "$_id",
            album_name: "$album_name",
            album_description: "$album_description",
            emoji_id: "$emoji_id",
            photo: {
                $filter : {
                    input: "$photo",
                    as : "photo_field",
                    cond : {
                        $eq: ["$$photo_field.flag",1]
                    }
                }
            }
        }
    },
    {
         $lookup:{
            from:"emoji",
            localField:"album_emoji",
            foreignField:"_id",
            as:"emoji"
         }
    },
    {
         $project:{
            album_name:"$album_name",
            album_description:"$album_description",
            emoji:"$emoji",
            photo:"$photo",
            total_photos: {$size: "$photo"}
         }
    }
])
Rohit Basu

Your query is wrong. What is localField:"album_emoji", there is no field named album_emoji in Album collection. The field name is album_id in Album collection which is a foreign key to _id in Emoji collection.

If you are using version 3.5, the correct query is (I assume Album, Photo, Emoji are the names of three collections):

 db.Album.aggregate([
  {
   $lookup:{
    from:"Photo",
    localField:"_id",
    foreignField:"album_id",
    as:"photo"
 }
},
{
 $match:{
    "photo.flag": 1
 }
},
{
 $lookup:{
    from:"Emoji",
    localField:"emoji_id",
    foreignField:"_id",
    as:"emoji"
 }
},
{ 
 $project:{
    album_name:"$album_name",
    album_description:"$album_description",
    album_emoji:"$emoji.emoji_name",
    photo:"$photo",
    total_photos: {$size: "$photo"}
 }
}

]).pretty()

And the result is as follows:

/* 1 */
{
 "_id" : 1,
 "album_name" : "my album 1",
 "album_description" : "album description 1",
 "album_emoji" : [
    "1.jpg"
 ],
 "photo" : [
    {
        "_id" : 1,
        "photo_name" : "1.jpg",
        "photo_description" : "description 1",
        "album_id" : 1,
        "flag" : 1
    },
    {
        "_id" : 2,
        "photo_name" : "2.jpg",
        "photo_description" : "description 2",
        "album_id" : 1,
        "flag" : 1
    },
    {
        "_id" : 3,
        "photo_name" : "3.jpg",
        "photo_description" : "description 3",
        "album_id" : 1,
        "flag" : 1
    }
 ],
 "total_photos" : 3
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!