Запрос на основе пустого массива и несуществующего поля с другими условиями в выражении - PullRequest
0 голосов
/ 10 марта 2020

У меня есть такие документы, как

{
     '_id': ...  
     'registration_temp_perm_no' => 'SIEI/216/2020',
     'first_name' => 'Azra',
     'last_name' => 'Ali'
},
{
     '_id': ...  
     'registration_temp_perm_no': ....
     'first_name': ...,
     'last_name' : ...,
     'transport_details' : [
         {
           ... 
           status : "Inactive"
         }
     ]  
},
{
     '_id': ...  
     'registration_temp_perm_no':...
     'first_name' : ....
     'last_name': .....,
     'transport_details': []
}

Обратите внимание, что документы создаются / обновляются с помощью функциональных возможностей внешнего интерфейса следующими тремя способами:

  1. , где встроенный документ 'transport_details 'вообще не существует.

  2. , где встроенный документ' transport_details 'содержит пустой массив

  3. , где встроенный документ' transport_details 'может содержать несколько вложенных массивы

Теперь я хочу получить те документы, в которых состояние последнего вложенного массива равно «Неактивно» или «Запрошено», а вспомогательный массив «transport_details» не существует и «transport_details» "пусто.

Я написал запрос наподобие

   $query =  array(
             '$or' => array(
                           array("first_name" => new MongoDB\BSON\Regex($arg, 'i')),
                           array("middle_name" => new MongoDB\BSON\Regex($arg, 'i')),
                           array("last_name" => new MongoDB\BSON\Regex($arg, 'i')),
                           array("registration_temp_perm_no" => $arg)
                         ),
                        "schoolId"=>  new MongoDB\BSON\ObjectID($this->schoolId),
                        '$expr' => [
                           '$or' => [
                              ['transport_details' => ['$exists' => false]],
                            ['transport_details' =>  ['$size' => 0]],

                            ['$eq'=> [['$arrayElemAt' => ['$transport_details.status', -1]], "Requested"]],
                            ['$eq'=> [['$arrayElemAt' => ['$transport_details.status', -1]], "Inactive"]],
                           ]
                        ]
                    );

Если мы удалим строки ['transport_details' => ['$ exist' => false]], ['transport_details' => ['$ size' => 0]], запрос может извлекать те документы, для которых состояние последнего подмассива имеет статус «Неактивно» или «Запрошено», в противном случае он не работает.

1 Ответ

0 голосов
/ 11 марта 2020

При использовании $expr все следующие операторы должны иметь синтаксис Выражения агрегации . Проверьте полный список здесь

Вам необходимо изменить

['transport_details' => ['$exists' => false]], 
['transport_details' => ['$size' => 0]]

на

['$eq'=> ['$transport_details', undefined]], //equivalent to {$exists:false}
['$eq'=> [['$size' => '$transport_details'], 0]] // $size returns number, we compare numbers

Если мы применяем оператор $IfNull, мы объединяем " не существует "+" пустой массив "в одном условии.

Попробуйте это:

db.collection.find({
  ... your extra conditions here
  $expr: {
    $or: [
      {
        $eq: [
          {
            $size: {
              $ifNull: [
                "$transport_details",
                []
              ]
            }
          },
          0
        ]
      },
      {
        $eq: [
          {
            $arrayElemAt: [
              "$transport_details.status",
              -1
            ]
          },
          "Requested"
        ]
      },
      {
        $eq: [
          {
            $arrayElemAt: [
              "$transport_details.status",
              -1
            ]
          },
          "Inactive"
        ]
      }
    ]
  }
})

MongoPlayground

...