purekid / mongodm

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

What is `_type` used for? #23

Open jrschumacher opened 10 years ago

jrschumacher commented 10 years ago

I am assuming it is used to maintain the association of an object if it doesn't have it's own collection like this.

class Person {
  public $collection = 'people';
}

class Student extends Person {}

However it adds a lot of unnecessary overhead to store _type unless someone is storing the different documents in the same collection. Let me know if this the only function because I want to build a dynamic switch (i.e. if there is no collection defined then set _type else omit)

Also I would suggest switching to a string rather than array. It is easier on the database with regards to storage and memory and would permit indexing. (i.e. Base\Person\Student)

purekid commented 10 years ago

'_type' is designed for retrieving a inheritance model.

class Animal {
  public $collection = 'animal';
}

class Mammal extends Animal {}
class Dog extends Mammal {}

$dog = new Dog('name'=>'Lucky');
$dog->save();

When retrieving a model,if we found this model have a parent class,we add '_type' to query params.

Query ['_type'=>'Dog']

$dog = Dog::one();

Query ['_type'=>'Mammal'] , Of course Dog belongs to Mammal,so we must retrieve the right dog .

$mammal = Mammal::one();

So in the db,the document of dog have a '_type' like this: ['Animal','Mammal','Dog'] And this is why '_type' stored as a array() in db.

purekid commented 10 years ago

And you says right , I also think the current method is not a very good solution . we must have some ways to optimize these code.

jrschumacher commented 10 years ago

So in short this enables the ability to fetch all documents related to the parent branch.

Functionality

Currently one can take Parent::find() to get all documents which is a child of Parent so considering the following model

class Person extends Model {
  public $collection = 'people';
}

class Faculty extends Person {}
class Tenyear extends Faculty {}
class Visiting extends Faculty {}

class Staff extends Person {}
class IT extends Staff {}
class Tenyear extends IT {}
class Financial extends Staff {}

class Student extends Person {
  public $collection = 'student';
}

one would expect

Person::one() // latest person in or extending Person (i.e. Faculty, Tenyear, Visiting, Staff, IT, etc...)
Faculty::one() // latest person in or extending Faculty
IT::one() // latest person in or extending IT
//....

Issues

Possible Solutions

  1. Detect Type based on PHP classes rather than Mongo query
    • How would a parent know it's children?
      • Load all models into memory and use foreach(get_declared_classes() as $c) if($c instanceof get_class()) x //...
    • Force convention and build an advanced query using the various children determined by convention
      • Naming convention
      • More restrictive on developer and possible difficult to integrate into existing applications
      • Namespace convention
      • Something like ParentNS/ParentCN
        • i.e. namespace Model/Person/Faculty/Tenyear
  2. Store type as hierarchical string using $regex
jrschumacher commented 10 years ago

@purekid do you have any more thoughts on this?

purekid commented 10 years ago

@jrschumacher,i have some ideas but not clear.I will do some test this night at home ,then continue here.

jrschumacher commented 10 years ago

@purekid Any thoughts about this?

jrschumacher commented 10 years ago

Also need to consider indexing cost of this. I've been running dex and it seems this has a cost on collections.