Search code examples
mongodbmongodb-queryaggregation-frameworkphp-mongodb

Lookup on the basis of embedded documrnt


I have a collection called assignmentTbl one record is stored as

    {
       _id : "6956GSVKU6535799",
       Type : "Project Abc",
       ...
       ...
       "TaskDetails"
        [
          { 
            "TaskId":"5759",
            "StudentId": ObjectId("5ab8845cff24ae1204000858"),
            ...
          },
          {
            "TaskId":"5659",
            "StudentId":  ObjectId("5ab8d7b1ff24ae1204000867"),
            ...
          }
          ...
        ]
    }

In studentTbl the data is like

   {
     "_id": ObjectId("5ab8d7b1ff24ae1204000867"),
     "profilePicture": "",
     "registration_temp_perm_no": "MGL-015",
     "admission_date": ISODate("2018-03-25T22:00:00.0Z"),
     "first_name": "Abrar",
     "middle_name": "",
     "last_name": "Khajwal",
     ...
   }
   ...
   ...

I want to write a query which will fetch data from assignment table and some student info (first_name and last_name) from studentTbl. Note that all the other fields from studentTbl are not required. I am not able to perform lookup aggregation on the basis of embedded document. Please help !!!

I have tried the below lines of code and it is returning empty.

public function fetchAllAllotments() 
{
    $pipeline = array(
        array(
            '$lookup' => array(
                'from' => 'studentTbl',
                'localField' => '_id',
                'foreignField' => 'TaskDetails.StudentId',
                'as' => 'StudentsDetails'
            )
        ), 

        array('$match' => array('id' => new MongoDB\BSON\ObjectID($this->id)))
    );

    try
     {
        $cursor = $this->collection->aggregate($pipeline);
     } 
     catch (Exception $e) {

     }

   return $cursor->toArray();
} 

Solution

  • You need to $unwind first and then you can apply $lookup stage... and also your localField should be TaskDetails.StudentId and foreignField should be _id

    public function fetchAllAllotments() 
    {
        $pipeline = array(
            array('$match' => array('id' => new MongoDB\BSON\ObjectID($this->id))),
            array('$unwind'=>'$TaskDetails'),
            array(
                '$lookup' => array(
                    'from' => 'studentTbl',
                    'localField' => 'TaskDetails.StudentId',
                    'foreignField' => '_id',
                    'as' => 'StudentsDetails'
                )
            )
        );
    
        try
         {
            $cursor = $this->collection->aggregate($pipeline);
         } 
         catch (Exception $e) {
    
         }
    
       return $cursor->toArray();
    }