(php) bsonUnserialize is called twice (on first element only) when calling find or when setting mapType on cursor

34 views
Skip to first unread message

Miguel

unread,
Mar 1, 2017, 3:42:49 PM3/1/17
to mongodb-user
Hi

When I call the method find (with no mapType), or when getting array from cursor when setting mapType, the bsonUnserialize method of the class contained in the collection is being called twice, but oddly enough only on the first element.


My collection has two elements of class Activity:


{ "_id" : ObjectId("58b6b5ae4da44a66493520a4"), "__pclass" : BinData(128,"QWN0aXZpdHk="), "type" : "activity" }


{ "_id" : ObjectId("58b6ba934da44a66985ef402"), "__pclass" : BinData(128,"QWN0aXZpdHk="), "type" : "activity" }



When I call find (not setting any mapType) to get all elements of this collection, this is what happens (log):



DEBUG - 2017-03-01 15:43:20 --> ======================in Activity::bsonUnserialize======================


DEBUG - 2017-03-01 15:43:20 --> data: array (


  '_id' =>


  MongoDB\BSON\ObjectID::__set_state(array(


     'oid' => '58b6b5ae4da44a66493520a4',


  )),


  '__pclass' =>


  MongoDB\BSON\Binary::__set_state(array(


     'data' => 'Activity',


     'type' => 128,


  )),


  'type' => 'activity',


)



DEBUG - 2017-03-01 15:43:20 --> ======================in Activity::bsonUnserialize======================


DEBUG - 2017-03-01 15:43:20 --> data: array (


  '_id' =>


  MongoDB\BSON\ObjectID::__set_state(array(


     'oid' => '58b6b5ae4da44a66493520a4',


  )),


  '__pclass' =>


  MongoDB\BSON\Binary::__set_state(array(


     'data' => 'Activity',


     'type' => 128,


  )),


  'type' => 'activity',


)


DEBUG - 2017-03-01 15:43:20 --> ======================in Activity::bsonUnserialize======================


DEBUG - 2017-03-01 15:43:20 --> data: array (


  '_id' =>


  MongoDB\BSON\ObjectID::__set_state(array(


     'oid' => '58b6ba934da44a66985ef402',


  )),


  '__pclass' =>


  MongoDB\BSON\Binary::__set_state(array(


     'data' => 'Activity',


     'type' => 128,


  )),


  'type' => 'activity',


)



As you can see, the first element of the collection (58b6b5ae4da44a66493520a4) is bsonUnserialized twice.



If I set the mapType to ['root' => 'array', 'document' => 'array', 'array' => 'array'] in method find, and then set the mapType to ['root' => NULL, 'document' => NULL, 'array' => NULL] in the cursor, the same happens:



DEBUG - 2017-03-01 12:27:30 --> ======================in Activity::bsonUnserialize======================


DEBUG - 2017-03-01 12:27:30 --> data: array (


  '_id' =>


  MongoDB\BSON\ObjectID::__set_state(array(


     'oid' => '58b6b5ae4da44a66493520a4',


  )),


  '__pclass' =>


  MongoDB\BSON\Binary::__set_state(array(


     'data' => 'Activity',


     'type' => 128,


  )),


  'type' => 'activity',


)


DEBUG - 2017-03-01 12:27:30 --> ======================in Activity::bsonUnserialize======================


DEBUG - 2017-03-01 12:27:30 --> data: array (


  '_id' =>


  MongoDB\BSON\ObjectID::__set_state(array(


     'oid' => '58b6b5ae4da44a66493520a4',


  )),


  '__pclass' =>


  MongoDB\BSON\Binary::__set_state(array(


     'data' => 'Activity',


     'type' => 128,


  )),


  'type' => 'activity',


)


DEBUG - 2017-03-01 12:27:30 --> ======================in Activity::bsonUnserialize======================


DEBUG - 2017-03-01 12:27:30 --> data: array (


  '_id' =>


  MongoDB\BSON\ObjectID::__set_state(array(


     'oid' => '58b6ba934da44a66985ef402',


  )),


  '__pclass' =>


  MongoDB\BSON\Binary::__set_state(array(


     'data' => 'Activity',


     'type' => 128,


  )),


  'type' => 'activity',


)




Does anybody know why this is happening? It seems to be useless to unserialize the first element twice, beside not making much sense.

I am using:
  • Mongodb v3.4.2
  • php version 7.0.15-0ubuntu0.16.04.2
  • ubuntu 16.04.2
  • MongoDB extension version 1.2.5

Any help would be much appreciated.

Many thanks in advance.

Miguel

Jeremy Mikola

unread,
Mar 1, 2017, 7:07:58 PM3/1/17
to mongodb-user
On Wednesday, March 1, 2017 at 3:42:49 PM UTC-5, Miguel wrote:
Hi

When I call the method find (with no mapType), or when getting array from cursor when setting mapType, the bsonUnserialize method of the class contained in the collection is being called twice, but oddly enough only on the first element.

The behavior you're seeing is due to logic in Cursor::setTypeMap(), which applies the type map to the cursor's current element. The driver tends to advance the cursor to the first document to check for an error between executing a query and initializing the MongoDB\Driver\Cursor object, which means that cursors always have a current element (unless there are no results) even before iteration begins. Combined with the fact that the PHP library tends to apply type maps to most cursors it creates before returning them to the user, we get the redundant conversion you're seeing.

Thanks for bringing this to our attention. I've opened PHPC-924 to track the bug. Please follow that issue for updates.

Jeremy Mikola

unread,
Mar 7, 2017, 2:53:10 PM3/7/17
to mongodb-user


On Wednesday, March 1, 2017 at 7:07:58 PM UTC-5, Jeremy Mikola wrote:

Thanks for bringing this to our attention. I've opened PHPC-924 to track the bug. Please follow that issue for updates.

The 1.2.6 release includes the fix for PHPC-924.
Reply all
Reply to author
Forward
0 new messages