简体   繁体   中英

How to add a condition inside $lookup in MongoDb .aggregate()?

persons collection:

{
  "_id": ObjectId("5f3258cfbaaccedaa5dd2c96"),
  "gender": "male",
  "name": {
    "title": "mr",
    "first": "victor",
    "last": "pedersen",//... more properties
} 

persondetails collection:

{
      "_id": ObjectId("5f3a91e68b1c26e68f9ed3ad"),
      "country": "India",
      "personid": ObjectId("5f3258cfbaaccedaa5dd2c96")
}

Get documents from persons along with associated persondetails where associated country in persondetails is "India

So if out of 10 persons only 3 are from India. I should get 3 person documents in resultset along with their associated persondetails

Query:

 [
    {
      "$match": {
      "$or": [
         
        {
          "$expr": {
            "$eq": [
              "$gender",
              "male"
            ]
          }
        }
      ]
    }
  },
  {
    "$facet": {
      "totalCount": [
        {
          "$count": "value"
        }
      ],
      "data": [
        {
          "$project": {
            "_id": "$_id",
            "fname": "$name.first",
            "lname": "$name.last",
            "dobage": "$dob.age",
            "registeredAge": "$registered.age"                
          }
        },
        {
          "$sort": {
            "name.first": 1
          }
        } ,
        {
          "$lookup": {
            "from": "persondetails",
            "localField": "_id",
            "foreignField": "personid", // how to add where clause in this lookup?
            "as": "persondetail" 
          }
        }
      ]
    }
  }
]

EDIT:

https://mongoplayground.net/p/3vBs6Frt-aK

Expected Result:

[
  {
    "data": [
      {
        "_id": ObjectId("5f3258cfbaaccedaa5dd2c96"),
        "fname": "victor",
        "lname": "pedersen",
        "persondetail": [
          {
            "_id": ObjectId("5f3a91e68b1c26e68f9ed3ad"),
            "country": "India",
            "personid": ObjectId("5f3258cfbaaccedaa5dd2c96")
          }
        ]
      }],
    "totalCount": [
      {
        "value": 1
      }
    ]
  }
]

There is a second $lookup syntax which allows you to specify custom filtering condition:

{
    "$lookup": {
        "from": "persondetails",
        "let": { person_id: "$_id" },
        "pipeline": [
            {
                $match: {
                    $expr: {
                        $and: [
                            { $eq: [ "$$person_id", "$personid" ] },
                            { $eq: [ "$country", "India" ] },
                        ]
                    }
                }
            }
        ],
        "as": "persondetail" 
    }
}

EDIT: You also need to add $match to filter out people with empty persondetail and if you want this to be included in your count then you need to run $facet as the last operation:

[
    {
        "$match": {
            "$or": [ {"$expr": { "$eq": [ "$gender", "male" ] } } ]
        }
    },
    {
        "$project": {
                "_id": "$_id",
                "fname": "$name.first",
                "lname": "$name.last",
                "dobage": "$dob.age",
                "registeredAge": "$registered.age"                
        }
    },    
    {
        "$lookup": {
            "from": "persondetails",
            "let": { person_id: "$_id" },
            "pipeline": [
                {
                    $match: {
                        $expr: {
                            $and: [
                                { $eq: [ "$$person_id", "$personid" ] },
                                { $eq: [ "$country", "India" ] },
                            ]
                        }
                    }
                }
            ],
            "as": "persondetail" 
        }
    },
    {
        $match: {
            persondetail: { $ne: [] }
        }
    },
    {
        $facet: {
            totalCount: [ { $count: "value" } ],
            data: [ { $sort: { "name.first": 1 } },  ]
        }
    }
]

Mongo Playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM