0

I want to retrieve a specific array from embedded document on matching base but either the output is displaying all arrays in that document not a specific one or displaying just the first array.... this is my code please have a look and answer this according to PHP.

$dept->findOne(['$and' => [
    ['_id' => 'd004'],
    ['dept_employees.from_date' => '1986-12-01'],
    ['dept_employees.to_date' => '9999-01-01']
                         ]
    ],
    ['projection' => ['dept_employees.$' => 1] ]);

this is the output

MongoDB\Model\BSONDocument::__set_state(array(
   '_id' => 'd004',
   'dept_employees' => 
  MongoDB\Model\BSONArray::__set_state(array(
     0 => 
    MongoDB\Model\BSONDocument::__set_state(array(
       'emp_id' => '10003',
       'from_date' => '1995-12-03',
       'to_date' => '9999-01-01',
    )),
  )),
))

the document is like this have 247 sub-arrays

MongoDB\Model\BSONDocument::__set_state(array(
   '_id' => 'd004',
   'dept_employees' => 
  MongoDB\Model\BSONArray::__set_state(array(
     0 => 
    MongoDB\Model\BSONDocument::__set_state(array(
       'emp_id' => '10003',
       'from_date' => '1995-12-03',
       'to_date' => '9999-01-01',
    )),
     1 => 
    MongoDB\Model\BSONDocument::__set_state(array(
       'emp_id' => '10004',
       'from_date' => '1986-12-01',
       'to_date' => '9999-01-01',
    )),
     2 => 
    MongoDB\Model\BSONDocument::__set_state(array(
       'emp_id' => '10010',
       'from_date' => '1996-11-24',
       'to_date' => '2000-06-26',
    )),

and i want only this

MongoDB\Model\BSONDocument::__set_state(array(
   '_id' => 'd004',
   'dept_employees' => 
  MongoDB\Model\BSONArray::__set_state(array(

     1 => 
    MongoDB\Model\BSONDocument::__set_state(array(
       'emp_id' => '10004',
       'from_date' => '1986-12-01',
       'to_date' => '9999-01-01',
    )),

Dates are here only as strings, i am just matching strings. The shell is also displaying same results:

db.departments.find( {"dept_employees.from_date": '1986-12-01',    
"dept_employees.to_date": '9999-01-01'}, {"dept_employees.$":1} ).pretty()
{
        "_id" : "d004",
        "dept_employees" : [
                {
                        "emp_id" : "10003",
                        "from_date" : "1995-12-03",
                        "to_date" : "9999-01-01"
                }
        ]
}
  • Use elemMatch for mulitple query criteria. Something like `db.departments.find( { dept_employees: { $elemMatch: { from_date: '1986-12-01', to_date: '9999-01-01' } } }, { "dept_employees.$": 1 } )`. More here https://docs.mongodb.com/manual/tutorial/query-arrays/#query-for-an-array-element-that-meets-multiple-criteria – s7vr Jul 12 '17 at 15:54
  • @Veeram thankx... your suggestion is working in mongo shell but not in PHP. `$dept->find( [ 'dept_employees' => [ '$elemMatch' => [ 'from_date' => '1986-12-01', 'to_date' => '9999-01-01' ] ] ], [ "dept_employees.$" => 1 ] ); ` displays only this **MongoDB\Driver\Cursor::__set_state(array())** – Iram Chauhdri Jul 12 '17 at 16:17
  • Try `findOne` or you have to iterate the results when using `find` – s7vr Jul 12 '17 at 17:13
  • @Veeram i tried findOne it displays all arays but in mongo shell it works right. i just pasted your first comment in mongo shell and it worked like charm. – Iram Chauhdri Jul 13 '17 at 07:28

1 Answers1

0

According to MongoDB documentation :

The positional $ operator limits the contents of an from the query results to contain only the first element matching the query document.

and :

See the aggregation operator $filter to return an array with only those elements that match the specified condition.

https://docs.mongodb.com/manual/reference/operator/projection/positional/

https://docs.mongodb.com/manual/reference/operator/aggregation/filter/#exp._S_filter

Also, not exactly sure in your case, but if you are looking to match date ranges, maybe using '$gt' and '$lt' can help.

Fabien
  • 4,862
  • 2
  • 19
  • 33
  • `db.departments.aggregate([ { $project: { dept_employees: { $filter: { input: "$dept_employees", as: "dept_employee", cond: { "$$dept_employee.emp_id": 10010 } } } } } ])` showing error – Iram Chauhdri Jul 12 '17 at 15:21
  • **"errmsg" : "Unrecognized expression '$$dept_employee.emp_id'"** – Iram Chauhdri Jul 12 '17 at 15:23