在mongo db php中根据嵌入式文档的最后一个元素的字段查找

时间:2018-08-24 12:04:20

标签: mongodb mongodb-query mongodb-php php-mongodb

我有一个集合studentTbl,其中包含类似的记录

记录1

 "_id": ObjectId("5b45d89bbbc51e2c2c006973")
 "first_name": "Pooja",
 ...
 contact_details[
    {
     ..
    },
    {
     ..
    }
 ]
  transport_details[
    {
      allotment_id:"68998546878",
      ..
      status:"Inactive"
    },
    {
      allotment_id:"25799856890",
      ..
      status:"Active"
    }
 ]
}

记录2

  "_id": ObjectId("5b45d89bbbc51e2c2533")
 "first_name": "Poornima",
 ...
 contact_details[
    {
     ..
    },
    {
     ..
    }
 ]
  transport_details[
    {
      allotment_id:"68998546878",
      ..
      status:"Inactive"
    }
 ]
}

记录3

 "_id": ObjectId("5b45d89bbbc51e2c2c00646")
 "first_name": "Poonam",
 ...
 contact_details[
    {
     ..
    },
    {
     ..
    }
 ]
  transport_details[
    {
      allotment_id:"68998546878",
      ..
      status:"Inactive"
    },
    {
      allotment_id:"25799856890",
      ..
      status:"Active"
    }
  ]
}

我正在尝试调整以下代码行,以获取其first_name或middle_name或last_name包含“ poo”并且在嵌入式文档transport_details的最后一个元素内,状态应该为“活动”的那些学生。如何编写这样的查询,该查询将基于名称查找学生并遍历嵌入式文档transport_details的最后一个元素,并检查状态是否为活动状态?例如,在上面的集合中,应该返回pooja和poonam。

代码就像

      // default if nothing is filled
      $query = array("schoolId"=>  new MongoDB\BSON\ObjectID($this->schoolId));

     // if name = filled, class = null, year = null 
     if(!empty($this->name) && empty($this->academicYearName) && empty($this->programId))
     {

           $param = preg_replace('!\s+!', ' ', $this->name);
           $arg = trim($param);

           $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)
                    );

     }
    ...
    ...
    ...
     $pipeline = array(
        array(
            '$match' => $query
        ),
        array(
            '$lookup' => array(
                'from' => 'programTbl',
                'localField' => 'classId',
                'foreignField' => '_id',
                'as' => 'ClassDetails'
            )
        ),
     );

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

    }

    return $cursor->toArray();

请注意,实际代码包含更多的条件$ query变量...

2 个答案:

答案 0 :(得分:1)

您可以在管道中添加以下阶段

array(
  "$match" => array(
    "$expr" => array(
      "$and" => [
        array(
          "$or" => [
            array( "$eq" => [ array( "$strcasecmp" => [ "$first_name", "Poo" ] ), 1 ] ),
            array( "$eq" => [ array( "$strcasecmp" => [ "$last_name", "Poo" ] ), 1 ] ),
            array( "$eq" => [ array( "$strcasecmp" => [ "$middle_name", "Poo" ] ), 1 ] ),
          ],
        ),
        array(
          "$eq" => [
            array( "$arrayElemAt" => [ array( "$slice"=> [ "$transport_details.status", -1 ] ), 0 ] ),
            "Active"
          ]
        )
      ]
    )
  )
)

答案 1 :(得分:1)

您可以在3.6中使用以下查询。

', '