Фильтр на проекции не работает в mongodb - PullRequest
0 голосов
/ 14 декабря 2018

Я выполнил агрегационный запрос к таблице ученика с таблицей действий, которая дает нужные поля, кроме одного, то есть «ActivityForMediumSize».Это поле пустое.

Код

  $query = ["is_temp_deleted"=>0, "funRun" => "Yes"];

        $pipeline = array(
            array(
                '$match' => $query
            ),
            array(
                '$lookup' => array(
                    'from' => 'studentTbl',
                    'localField' => '_id',
                    'foreignField' => 'activity_details.activityId',
                    'as' => 'studentsOfActivities'
                )
            ),
           ['$lookup'=> [
               'from'=> 'studentTbl',
               'localField' => 'academic_year_Id',
               'foreignField' => 'studentsOfActivities.academic_year_Id',
               'as'=> 'Students'
            ]],
            ['$project' => [
                '_id' => 1.0,
                'activityName' => 1.0,
                'activityTime' => 1.0,
                'activityDate' => 1.0,
                'funRun' => 1.0,
                'Students' => 1.0,
                'studentsOfActivities' => 1.0,
                'studentsOfWeekgroup' => [
                    '$filter' => [
                        'input' => '$Students',
                        'as' => 'item',
                        'cond' => [
                            '$eq' => ['$$item.academic_year_Id', new MongoDB\BSON\ObjectID($this->id)],

                        ]
                    ]
                ],
                'ActivityForMediumSize' => [
                    '$filter' => [
                        'input' => '$studentsOfActivities',
                        'as' => 'item',
                        'cond' => [
                            '$eq' =>['$$item.activity_details.-1.shirtSize', 'M'],
                        ]
                    ]
                ],

                'StudentCountPerActivity'=>['$size'=>'$studentsOfActivities'],
               // 'MediumCount'=>['$size'=>'$countForMedium']
              ]], 
            );

    $cursor =  $this->db->activitiesTbl->aggregate($pipeline)->toArray();

Я проверил в консоли, что данные в "StudentsOfActivities" выглядят как

   0 =>
    "_id": ObjectId("5bf518378d03ec0b2400536f"),
    "ssn_Last_four": "0001",
    "first_name": "Thomas",
    "activity_details": [
   {
      "studentId": ObjectId("5bf518378d03ec0b2400536f"),
      "funrun": "Yes",
      "weekgroupId": ObjectId("5bf50bd48d03ec0b2400536d"),
      "activityId": ObjectId("5c10a0e08d03ec1834001c6d"),
      "attending": "Yes",
       "id": ObjectId("5c10e5ae3250041188005dde") 
   },
   {
   "studentId": ObjectId("5bf518378d03ec0b2400536f"),
   "funrun": "Yes",
   "weekgroupId": ObjectId("5bf50bd48d03ec0b2400536d"),
   "activityId": ObjectId("5c10a0e08d03ec1834001c6d"),
   "attending": "Yes",
   "shirtSize": "L",
   "id": ObjectId("5c13338032500409f4007cf3") 
    }
   ] 
   1=>
     "_id": ObjectId("5bf518378d03ec0b2400536e"),
     ....
     .... 

Внедренный документ "activity_details"содержит все действия студента, и последний элемент считается активным, т. е. почему я использовал -1 в приведенном выше коде.

Теперь в проекции" ActivityForMediumSize "я пытаюсь найти тех студентов, которые выбрали shirtSize: "М".Фильтр на проекции "ActivityForMediumSize" не работает.Пожалуйста, помогите !!!

Обратите внимание, что есть некоторые ученики, у которых последнее действие внутри "activity_details" не содержит поля "shirtSize".

1 Ответ

0 голосов
/ 14 декабря 2018

Я думаю, "не работает" означает, что у вас есть пустой массив.Это потому, что вы не можете ссылаться на последний элемент массива просто с помощью «-1».Вместо этого вам нужно использовать операторы массива, чтобы получить последний элемент.Например, это может быть комбинация arrayElemAt и slice , поэтому условие фильтра может выглядеть следующим образом:

$eq: [
    { $let: {
        vars: {
            last: { $arrayElemAt: [ 
                { $slice: [ '$$item. activity_details', -1 ] },
                0   
            ] }
        },
        in: '$$last.shirtSize'
    } },
    'M'
]

Это в синтаксисе js, но оно должно быть тривиальным дляперевести на php.

...