coen-hyde / Shanty-Mongo

Shanty Mongo is a mongodb library for the Zend Framework. Its intention is to make working with mongodb documents as natural and as simple as possible. In particular allowing embedded documents to also have custom document classes.
Other
200 stars 52 forks source link

Document set containing document with DocumentSet #43

Open tholder opened 13 years ago

tholder commented 13 years ago

This may not be a bug but something is up with it.

If you have a document structured like:

company --->categories [DocumentSet] --------->category ---------------->access [DocumentSet] ----------------------->access

You can't do this:

$c = $company->categories->new(); $c->name = 'My Cat'; $c->save();

$a = $c->access->new(); $a->hasAccess = true; $a->save();

When calling second save I get:

MongoCursorException: can't append to array using string field name [access] in on line 948

It's not clear the correct order in which to be saving things. I have, accidentally, managed to get it saving correctly once but I've just lost the correct combination. Will add it when I find it.

tholder commented 13 years ago

I think I've found that it has to be done as follows:

$c = $company->categories->new(); $c->name = 'My Cat'; $company->categories->addDocument($c); $company->categories->save();

$a = $c->access->new(); $a->hasAccess = true; $c->access->addDocument($a); $c->access->save();

This doesn't seem very intuitive imho, either that or I've been in the land of document databases too long today! I'll add something to the wiki if that's ok.

coen-hyde commented 13 years ago

Yeah, working with document databases expecting relational functionality is going to end messy. Shanty Mongo to some degree elevates the gap but it only gets so far. There are two issues you've run into.

  1. At the moment it's impossible to update an array element in a nested array https://jira.mongodb.org/browse/SERVER-831

Your work around works because you're saving the entire array inside an array not an array element in a nested array.

  1. When you do:

    $c = $company->categories->new(); $c->name = 'My Cat'; $c->save();

$c gets pushed into categories on the db end. So unfortunately we then have an incomplete path to $c (we do not know its index). This means you wont be able to save its self or children anymore. A work around is to do:

$c = $company->categories->new(); $c->name = 'My Cat'; $company->categories->addDocument($c); $company->categories->save();

as you figured out but the problem with this in high concurrent connections is you run the possibility of overriding categories with stale data because you're saving the entire categories array.