Ben Coffin
Ben Coffin

Reputation: 607

Combining '$or' and daterange

I'm getting the following fault while trying to combine '$or' with date range using the MongoDB PHP Driver: Fatal error: Uncaught exception 'MongoCursorException' with message '$and/$or/$nor must be a nonempty array' in [FILE.php]:67

Here's my query criteria:

Array
(
    [$and] => Array
        (
            [0] => Array
                (
                    [fileowner] => 51f17509d5cddc2d52000000
                )
            [1] => Array
                (
                    [$or] => Array
                        (
                           [created] => Array
                                (
                                    [$gt] => 1367812800
                                    [$lt] => 1367899200
                                )
                            [accessed] => Array
                                (
                                    [$gt] => 1367812800
                                    [$lt] => 1367899200
                                )

                        )

                )

        )

)

Shouldn't i be able to combine these conditionals this way?

Upvotes: 0

Views: 554

Answers (3)

Derick
Derick

Reputation: 36784

You need an extra array around the criteria, you used:

'$or' => array(
    'created'  => array( '$gt' => 1367812800, '$lt' => 1367899200 ),
    'accessed' => array( '$gt' => 1367812800, '$lt' => 1367899200 )
);

But what you need is:

'$or' => array(
    array( 'created'  => array( '$gt' => 1367812800, '$lt' => 1367899200 ) ),
    array( 'accessed' => array( '$gt' => 1367812800, '$lt' => 1367899200 ) )
);

$or accepts an array and not an associative array. In PHP, those have the same syntax array(), where in JavaScript/JSON, it is either [..] vs. {..}. In PHP the distinction lies in whether you have numbers (or nothing as keys) or strings as keys (created / accessed) as top level.

Converting a JSON/BSON query syntax into PHP is not really that difficult, and I suggest you do some research on how to do this. It basically means: change [ and { to array(, and ] and } to ).

Upvotes: 2

Dante Ditan
Dante Ditan

Reputation: 34

You should assign a key not a variable to the index array. For example:

function getImportPostcardMerge($daily) {        
  $s_e = getSerAndEquip();

  $mergearr = array();
  foreach ($daily as $rw) {      
    foreach ($s_e as $ks => $serv) {       
      if ($rw[0] == $serv['tracking_no']) { 
        $mergePO = array_merge($rw, $serv);
        $mergearr[$ks] = $mergePO;
      }    
    }   
  }
  return $mergearr;    
}

Upvotes: 0

Chris Heald
Chris Heald

Reputation: 62648

$or takes an array (in the common sense, not in the PHP sense; hashmaps are not valid).

The Javascript(/BSON) version is something like this:

$or: [
    {created: {$gt: 1367812800}, accessed: {$gt: 1367812800}},
    {created: {$gt: 1367812800}, accessed: {$lt: 1367899200}},
    {created: {$lt: 1367899200}, accessed: {$gt: 1367812800}},
    {created: {$lt: 1367899200}, accessed: {$lt: 1367899200}},
] 

That is, $or takes a list of criteria, and will return documents which match any one of them. I'm making assumptions about what you actually want here, but I may have misinterpreted your original query.

If you're looking for files that have been created or accessed in the given date range, you want something like:

$or: [
  {created:  {$gt: x, $lt: y}},
  {accessed: {$gt: x, $lt: y}}
]

Note that $or contains an array of criteria, not a hashmap.

Upvotes: 0

Related Questions