Array values being saved in the root document in MongoDB #373

Closed
philearl opened this Issue Mar 11, 2012 · 9 comments

Comments

Projects
None yet
5 participants

I've noticed that when updating a record that has an inner array, those values are being written outside of the array document. A test example would be as follows:

$data = Data::create();
$data->save();
$id = $data->_id;
Data::update(array('$push'=>array('testArray'=>array('key'=>'value'))),array('_id'=>$id));

At this point, the structure is:

[_id] => MongoId Object (
    [$id] => 4f5ccc670b7aab6310000008
)
[created] => 2012-03-11 16:01:43
[last_modified] => 2012-03-11 16:01:43
[testArray] => Array (
    [0] => Array (
        [key] => value
    )
 )

If the following is then run:

    $newdata = Data::find('first',array('conditions'=>array('_id'=>$id)));
    $newdata->save(array('new_value'=>'something'));

The structure changes to the following:

[_id] => MongoId Object (
    [$id] => 4f5ccc670b7aab6310000008
)
[created] => 2012-03-11 16:01:43
[last_modified] => 2012-03-11 16:01:43
[new_value] => something
[testArray] => Array (
    [0] => Array (
        [key] => value
    )
)
[0] => Array (
     [key] => value
)

You can see that now the values from the inner array 'testArray' have appeared in the root of the document.

For transparency, the Data model looks like thus:

namespace app\models;

class Data extends \lithium\data\Model {
    protected $_meta = array('key' => '_id');
}

Data::applyFilter('save', function($self, $params, $chain){
    $document = $params['entity'];
    if (!$document->_id) {
        $document->created = date('Y-m-d H:i:s');
    }
    $document->last_modified = date('Y-m-d H:i:s');
    if (!empty($params['data'])) {
        $document->set($params['data']);
    }
    $params['entity'] = $document;
    return $chain->next($self, $params, $chain);
});
Member

marcghorayeb commented Mar 11, 2012

I might be mistaken but this is going/should be fixed in the upcoming data branch merge.

Owner

nateabele commented Mar 11, 2012

Yes, please do a checkout of the data branch and let me know if this is still an issue.

danives commented Mar 12, 2012

Hey - I happened to post this while logged in to a different account, but thought I would continue with my actual one.

I checked out the latest lithium library, and that doesn't happen anymore - but something (possibly worse) does. This is the initial state:

  [_id] => MongoId Object (
      [$id] => 4f5ccc670b7aab6310000008
  )
  [created] => 2012-03-11 16:01:43
  [last_modified] => 2012-03-11 16:01:43
  [testArray] => Array (
      [0] => Array (
          [key] => value
      )
   )

Now after doing the same save, this happens:

[_id] => MongoId Object (
    [$id] => 4f5df98daffd4c343f000000
)
[created] => 2012-03-12 13:26:37
[last_modified] => 2012-03-12 13:27:48
[new_value] => something
[testArray] => Array (
    [0] => Array (
    [key] => value
    )
    [1] => Array (
    [key] => value
    )
)

If I do the save again:

[_id] => MongoId Object (
    [$id] => 4f5df98daffd4c343f000000
)
[created] => 2012-03-12 13:26:37
[last_modified] => 2012-03-12 13:27:48
[new_value] => something
[testArray] => Array (
    [0] => Array (
    [key] => value
    )
    [1] => Array (
    [key] => value
    )
    [2] => Array (
    [key] => value
    )
    [3] => Array (
    [key] => value
    )
)

So now it seems to be duplicating the items within the array itself. This is using a full copy of the library that I took yesterday. Same code as in the original issue was used to duplicate.

Owner

nateabele commented Mar 12, 2012

Okay, but is this on the master branch or the data branch?

danives commented Mar 14, 2012

Sorry, that was on the master branch; I misinterpreted what you said.

I took a copy of the data branch and used that, however now I get an error:

Fatal error: Declaration of lithium\data\collection\DocumentArray::offsetGet() must be compatible with that of     ArrayAccess::offsetGet() in /Work/latest-lithium/lithium/data/collection/DocumentArray.php on line 145

Does appear to happen when I do the second save call:

$newdata = Data::find('first',array('conditions'=>array('_id'=>$id)));
$newdata->save(array('new_value'=>'something'));
Owner

nateabele commented Mar 14, 2012

That's odd, I just ran the test case for DocumentArray and I don't get any such errors. What version of PHP?

danives commented Mar 15, 2012

Looks like I'm using 5.3.4

It saves fine the first time, and I'm sure it probably would again, but I think when

Data::update(array('$push'=>array('testArray'=>array('key'=>'value'))),array('_id'=>$id));

is run, then retrieving it and saving it is possibly causing the error?

In fact omitting that call it works without issue; it's that inner array that seems to cause the issue.

danives commented Mar 15, 2012

Slight update - I reverted to my existing library and the problem seems to have stopped. I haven't changed anything within the bugTest code, or the model that is being used.

However the above error still happens when on the data branch, and the prior error still happens (inner duplication) on the master branch. I believe I am locally running 'lithium-0_10'.

@ghost ghost assigned nateabele May 23, 2012

Contributor

jails commented Jul 15, 2012

Yeah I also get the error : "Fatal error: Declaration of lithium\data\collection\DocumentArray::offsetGet() must be compatible with that of ArrayAccess::offsetGet()".
It happens when I works a PHP version < 5.3.4. (see notes on http://www.php.net/manual/en/arrayaccess.offsetget.php)
So imo this issue can be closed since it works on the data branch.

@nateabele nateabele closed this Jul 15, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment