Mongodm : 一個PHP的mongo ORM 操作元件
阿新 • • 發佈:2018-12-24
PHP提供的一系列的Mongo操作類已經很強大了. 但是仍然不是很友好.這在以前使用的時候就有感觸, 當時是自己團隊寫的一套封裝, 也經常出現種種的問題.
目前在用Phalcon, 框架還在發展階段, 只提供了cache類操作.
在github和mongodb官網上尋找成熟的優秀的元件, 找到不少, 琳琅滿目, 新舊不一, 我從中找了一個說明文件詳細,更新及時,維護完善的專案: Mongodm.
特點
orm
簡單,靈活
支援嵌入
支援引用
支援多級繼承
支援本地收集操作
資料庫配置
或者使用內建方法配置:return array( 'default' => array( 'connection' => array( 'hostnames' => 'localhost', 'database' => 'default', // 'username' => '', // 'password' => '', ) ), 'production' => array( 'connection' => array( 'hostnames' => 'localhost', 'database' => 'production', 'options' => array('replicaSet' => 'rs0') ) ) );
\Purekid\Mongodm\MongoDB::setConfigBlock('default', array( 'connection' => array( 'hostnames' => 'localhost', 'database' => 'default', 'options' => array() ) )); // \Purekid\Mongodm\MongoDB::setConfigBlock('auth', array( 'connection' => array( 'hostnames' => 'localhost', 'database' => 'authDB', 'options' => array() ) ));
建立模型:
模型屬性:class User extends \Purekid\Mongodm\Model { static $collection = "user"; /** use specific config section **/ public static $config = 'testing'; /** specific definition for attributes, not necessary! **/ protected static $attrs = array( // 1 to 1 reference 'book_fav' => array('model'=>'Purekid\Mongodm\Test\Model\Book','type'=>'reference'), // 1 to many references 'books' => array('model'=>'Purekid\Mongodm\Test\Model\Book','type'=>'references'), // you can define default value for attribute 'age' => array('default'=>16,'type'=>'integer'), 'money' => array('default'=>20.0,'type'=>'double'), 'hobbies' => array('default'=>array('love'),'type'=>'array'), 'born_time' => array('type'=>'timestamp'), 'family'=>array('type'=>'object'), 'pet_fav' => array('model'=>'Purekid\Mongodm\Test\Model\Pet','type'=>'embed'), 'pets' => array('model'=>'Purekid\Mongodm\Test\Model\Pet','type'=>'embeds'), ); public function setFirstName($name) { $name = ucfirst(strtolower($name)); $this->__setter('firstName', $name); } public function getLastName($name) { $name = $this->__getter('name'); return strtoupper($name); } }
$types = [
'mixed', // mixed type
'string',
'reference', // 1 : 1 reference
'references', // 1 : many references
'embed',
'embeds',
'integer',
'int', // alias of 'integer'
'double', // float
'timestamp', // store as MongoTimestamp in Mongodb
'date', // store as DateTime
'boolean', // true or false
'array',
'object'
]
建立(Create)
$user = new User();
$user->name = "Michael";
$user->age = 18;
$user->save();
帶初始值:
$user = new User( array('name'=>"John") );
$user->age = 20;
$user->save();
使用賦值的方式:
$user->setLastName('Jones'); // Alias of $user->lastName = 'Jones';
$user->setFirstName('John'); // Implements setFirstName() method
可以set/get value 通過屬性: $user->name = "kevin" 或者通過方法: $user->getName().
// SET:
// no "set" method exists
$user->lastName = 'Jones';
$user->setLastName('Jones');
// "set" method exists implements setFirstName()
$user->firstName = 'jOhn'; // "John"
$user->setFirstName('jOhn'); // "John"
// =========
// GET:
// "get" method exists implements getLastName()
print $user->lastName; // "JONES"
print $user->getLastName(); // "JONES"
// no "get" method
print $user->firstName; // "John"
print $user->setFirstName('John'); // "John"
更新(Update)
$user->age = 19;
更新陣列:
$user->update( array('age'=>18,'hobbies'=>array('music','game') ) );
$user->save();
釋放(unset)屬性:
$user->unset('age');
$user->unset( array('age','hobbies') )
檢索一條記錄
$user = User::one( array('name'=>"michael" ) );
通過Id檢索一條記錄:
$id = "517c850641da6da0ab000004";
$id = new \MongoId('517c850641da6da0ab000004'); //another way
$user = User::id( $id );
檢索多條記錄
$params = array( 'name'=>'Michael','books'=>array('$size'=>2) );
$users = User::find($params); // $users is instance of Collection
echo $users->count();
檢索所有記錄
$users = User::all();
統計記錄(COUNT)
$count = User::count(array('age'=>16));
刪除記錄
$user = User::one();
$user->delete();
例項參考 -- 關係
一對一關係:
$book = new Book();
$book->name = "My Love";
$book->price = 15;
$book->save();
// !!!remember you must save book before!!!
$user->book_fav = $book;
$user->save();
// now you can do this
$user = User::one( array('name'=>"michael" ) );
echo $user->book_fav->name;
一對多關係:
$user = User::one();
$id = $user->getId();
$book1 = new Book();
$book1->name = "book1";
$book1->save();
$book2 = new Book();
$book2->name = "book2";
$book2->save();
$user->books = array($book1,$book2);
//also you can
$user->books = Collection::make(array($book1,$book2));
$user->save();
//somewhere , load these books
$user = User::id($id);
$books = $user->books; // $books is a instance of Collection
例項參考 -- 內嵌
單一嵌入:
$pet = new Pet();
$pet->name = "putty";
$user->pet_fav = $pet;
$user->save();
// now you can do this
$user = User::one( array('name'=>"michael" ) );
echo $user->pet_fav->name;
嵌入集合:
$user = User::one();
$id = $user->getId();
$pet_dog = new Pet();
$pet_dog->name = "puppy";
$pet_dog->save();
$pet_cat = new Pet();
$pet_cat->name = "kitty";
$pet_cat->save();
$user->pets = array($pet_cat,$pet_dog);
//also you can
$user->pets = Collection::make(array($pet_cat,$pet_dog));
$user->save();
$user = User::id($id);
$pets = $user->pets;
收集器:
下面$user是收集的例項:
$users = User::find( array( 'name'=>'Michael','books'=>array('$size'=>2) ) );
$users_other = User::find( array( 'name'=>'John','books'=>array('$size'=>2) ) );
count:
$users->count();
$users->isEmpty();
迭代: foreach($users as $user) { }
// OR use Closure
$users->each(function($user){
})
排序:
//sort by age desc
$users->sortBy(function($user){
return $user->age;
});
//sort by name asc
$users->sortBy(function($user){
return $user->name;
} , true);
//reverse collection items
$users->reverse();
Slice and Take:
$users->slice(0,1);
$users->take(2);
Map:
$func = function($user){
if( $user->age >= 18 ){
$user->is_adult = true;
return $user;
}
};
$adults = $users->map($func);
// Notice: 1. $adults is a new collection 2. In original $users , data has changed at the same time.
Filter:
$func = function($user){
if( $user->age >= 18 ){
return true;
}
}
$adults = $users->filter($func); // $adults is a new collection
確保集合中的一條記錄存在於例項中:
$john = User::one(array("name"=>"John"));
$users->has($john)
確保集合中的記錄存在數字索引: $users->has(0)
確保記錄存在MONGOID:
$users->has('518c6a242d12d3db0c000007')
通過數字索引獲得一條記錄:
$users->get(0)
通過MONGOID獲得一條記錄:
$users->get('518c6a242d12d3db0c000007')
通過數字索引刪除一條記錄:
$users->remove(0)
通過MONGOID刪除一條記錄:
$users->remove('518c6a242d12d3db0c000007')
新增一條記錄到收集器中:
$bob = new User( array("name"=>"Bob"));
$bob->save();
$users->add($bob);
新增多條記錄到收集器中:
$bob = new User( array("name"=>"Bob"));
$bob->save();
$lisa = new User( array("name"=>"Lisa"));
$lisa->save();
$users->add( array($bob,$lisa) );
合併兩個收集器:
$users->add($users_other); // the collection $users_other appends to end of $users
匯出資料到一個數組:
$users->toArray();
繼承
定義多級繼承類:
use Purekid\Mongodm\Model;
namespace Demo;
class Human extends Model{
static $collection = "human";
protected static $attrs = array(
'name' => array('default'=>'anonym','type'=>'string'),
'age' => array('type'=>'integer'),
'gender' => array('type'=>'string'),
'dad' => array('type'=>'reference','model'=>'Demo\Human'),
'mum' => array('type'=>'reference','model'=>'Demo\Human'),
'friends' => array('type'=>'references','model'=>'Demo\Human'),
)
}
class Student extends Human{
protected static $attrs = array(
'grade' => array('type'=>'string'),
'classmates' => array('type'=>'references','model'=>'Demo\Student'),
)
}
使用:
$bob = new Student( array('name'=>'Bob','age'=> 17 ,'gender'=>'male' ) );
$bob->save();
$john = new Student( array('name'=>'John','age'=> 16 ,'gender'=>'male' ) );
$john->save();
$lily = new Student( array('name'=>'Lily','age'=> 16 ,'gender'=>'female' ) );
$lily->save();
$lisa = new Human( array('name'=>'Lisa','age'=>41 ,'gender'=>'female' ) );
$lisa->save();
$david = new Human( array('name'=>'David','age'=>42 ,'gender'=>'male') );
$david->save();
$bob->dad = $david;
$bob->mum = $lisa;
$bob->classmates = array( $john, $lily );
$bob->save();
檢索並檢查value:
$bob = Student::one( array("name"=>"Bob") );
echo $bob->dad->name; // David
$classmates = $bob->classmates;
echo $classmates->count(); // 2
var_dump($classmates->get(0)); // john
獲取子類:
獲取所有Humans record , 查詢不用_type, 因為他是一個頂級類:
$humans = Human::all();
獲取所有Student records , 查詢是i用 { "_type":"Student" } , 因為他是一個子類:
$students = Student::all();
查詢子類不用_type:
To retrieve a record without the _type criteria (i.e. { "_type":"Student" }) set:
class Student extends \Purekid\Mongodm\Model
{
protected static $useType = false;
protected static $collection = 'Student';
}
Make sure to set a collection otherwise you will get results with every _type.
其他的模型靜態方法
User::drop() // Drop collection
User::ensureIndex() // Add index for collection
模型鉤子
The following hooks are available:
__init()
Executed after the constructor has finished
__preInsert()
Executed before saving a new record
__postInsert()
Executed after saving a new record
__preUpdate()
Executed before saving an existing record
__postUpdate()
Executed after saving an existing record
__preSave()
Executed before saving a record
__postSave()
Executed after saving a record
__preDelete()
Executed before deleting a record
__postDelete()
Executed after deleting a record