purekid / mongodm

MongoDB ORM that includes support for references,embed and multilevel inheritance.
MIT License
200 stars 47 forks source link

Model (with Reference to Json) #75

Closed joesonw closed 10 years ago

joesonw commented 10 years ago

I have a function need to return a model in json (with all fields, several of them are references). The output, however, only gives "$id" and "$ref" fields instead of the referenced object.

purekid commented 10 years ago

Maybe we can extend toArray() with parameter $loadRef = false .

jrschumacher commented 10 years ago

@joesonw @purekid this has already been discussed and added in a patch way see #48

The issue with this is two part, which #48 addresses, 1. which references do you want to load and 2. recursion.

  1. Let's say you have an document with 100 references. You make the first request to the server for this document and then you make 100 more requests for the immediate children of this document. Given a completely random ~200ms turnaround time, this would be 200 * 100 + 1 = 200200ms = 20.2s until everything is loaded.
  2. Lets consider a single document with one reference to itself. Now we have an infinite loop.

So in the time being the easiest solution is to add this logic manually which allows the developer to control the above issues:

$docCur = Model::find();

$result = array();
foreach($docCur as $doc) {
  $array = $doc->toArray();
  $doc['ref1'] = $doc->ref1->toArray();
  $ref2['ref2'] = $doc->ref2->toArray();
  //...

  $result[] = $array;
}

But a better designed solution would be to create something like this where you map out what you want the data to look like.

  $doc->toArray(array(
    'ref1' => array(
      'load' => true,
      'map' => array(
        'ref1a' => true,
        'ref1b' => array('load' => true, 'map' => array('ref1b1' => true))
      )
    )
  ));

We need to figure out caching so if ref1a is requested already we can load from cache rather than make another database call


On a completely separate note I often use the $id and $ref above to make Async requests from my frontend for more information. Or I mash it up in the frontend based on that data.

jrschumacher commented 10 years ago

@joesonw reopen if you still need help