sokil/php-mongo

DBRefs support

ramzes13 opened this issue · 8 comments

Hello,

I'm trying to set up relationships for 2 objects like in documentation.
On Mongo server relations betwen objects are saved like there https://docs.mongodb.com/manual/reference/database-references/

I think that this mechanism has not been implemented to work on this odm,
please tell me if i am wrong.

sokil commented

No, there are no special logic for DBRefs. By the way DBRef is only array with collection name and document id inside, so you can handle this manually, or by using http://www.php.net/manual/en/class.mongodbref.php/

What do you exprect from DBref in ODM, maybe there is a reason to implement.

I have an existing database with a defined structure.
Ex:

{
"name": "test",
"email": "mail@mail.com",
"posts": [
  {"$ref": "Post", "$id": ObjectId("5238a73db3d55c6883304972"), "$db": local},
  {"$ref": "Post", "$id": ObjectId("5238a73db3d55c6883304973"), "$db": local},
  {"$ref": "Post", "$id": ObjectId("5238a73db3d55c6883304974"), "$db": local}
]
}
}

After I defined the documents and mapping, they don't work correctly.
I think it would be good to use for mapping DBRefs strcture by default, and to discourage the use of other structures like array of ids.

sokil commented

You mean to get list of Post instances instead of array?

<?php
$posts = $user->get('posts'); // array of Post instances

yes
now, without mapping, I get array of DBRefs :)
If I configure the mapping (User and Post) : $posts = $user->get('posts'); empty result

With DBRefs User document could instantiate Post documents without any mapping config.

sokil commented

Instantiating of Post documents imposible without mapping in any kind. It may me done througn relations https://github.com/sokil/php-mongo#relations in php code, or you can use DBRefs and store collection name in EVERY post record? and then write you logic for instantiating Post instance by ref. DBRefs may be good if documents from different collections linked, in other cases its consumption of hadr drive space. For MongoDB internally its just an array and its stored as array, and only drivers MAYBE use this arrays as refs.

sokil commented

http://php.net/manual/ru/mongocollection.getdbref.php
We need dereference manually this field.

Currentry you may try to add something like that:

<?php
$user->getPosts();

class User
{
    public function getPosts()
    {
         $posts = [];
         $nativeCollection = $this->getCollection()->getMongoCollection();
         foreach ($this->get('posts') as $postDbRef)
         {
                $posts[] = $nativeCollection->getDBRef($postDbRef);
         }

         return $posts;
    }
}

But this implementation in not well in case of persormance, it will load every post from db in loop, so to get posts we need to get all records from collection at once.

And i'll try to add something more useful soon.

Ok, thanks for the reply