views:

44

answers:

2

I've been playing around with Mongo for about a week now and I still can't work out how to modify nested arrays in Mongo with php.

So here is a sample document...

array (
  '_id' => new MongoId("4cb30f560107ae9813000000"),
  'email' => '[email protected]',
  'firstname' => 'Maurice',
  'lastname' => 'Campobasso',
  'password' => 'GOD',
  'productions' => 
  array (
    0 => 
    array (
      'title' => 'a',
      'date' => '1286811330.899',
    ),
    1 => 
    array (
      'title' => 'b',
      'date' => '1286811341.183',
    ),
    2 => 
    array (
      'title' => 'c',
      'date' => '1286811350.267',
    ),
    3 => 
    array (
      'title' => 'd',
      'date' => '1286811356.05',
    ),
  ),
)

What I wan't to do is delete an array inside the productions array, but I can't work out how. I've been playing with 'update('$pull' => ...etc)' but I haven't been able to make it work.

+2  A: 

That is actually very easy, unlike traditional sql stuff you just modify the whole data and pass it back.

$cursor = $mongo->yourDB->yourCollection->findOne("_id",4cb30f560107ae9813000000);
//let's remove last item on productions
array_splice($cursor["productions"],2);
//and update the mongo document
echo $mongo->yourDB->yourCollection->update($cursor);
//it echoes 1 if successful

hope it helps.

Sinan Y.
Thanks Sinan I'll give it a shot. I do have to ask though, if productions was a much bigger array wouldn't an operation like that be really slow.
cybermotron
That was an example of a single document update. If i get your question right, there is a restriction of Mongo which says that you can put 4mb into a single document, if you plan to put larger documents you need to setup gridFS afaik. I am using a huge Mongo db on a web-app and it processes such cases pretty fast.
Sinan Y.
Thanks for clarifying, as I said I'm just beginning with Mongo.
cybermotron
you're welcome and as a SO tip don't forget to upvote answers you found useful ;)
Sinan Y.
+2  A: 

OK, there are a few ways to do this. In your case, I would do something like

mymongoobject.update( $unset : { "productions.2" : 1 } }

That's basically saying to unset the ".2" element of productions. Some docs here.

Now $pull should also work, but it's a little tougher because "productions" is actually an array of arrays (or objects with sub-objects). So you'd have to match arrays exactly:

mymongoobject.update( $pull : { "productions" : {'title':'d', 'date':'1286811356.05'} }

In the case above, the unset is probably the easiest option (though it will leave a "hole" in the array)

Gates VP
Unset worked, but you're right it left a dirty big hole in my database, that trips up the javascript in my app.
cybermotron
Pull worked just fine!!
cybermotron
Awesome. Good to know the $pull worked. Of course, the $pull really sucks if you have big objects, so it's worth knowing both methods. The javascript syntax for dealing with "holes" is to use `for(var i in values) { values[i]; }` This will dance around the "holes".
Gates VP