suren/laravel-mongo-model-schema

使 MongoDB 数据的保存和检索与定义的架构相匹配,支持嵌套数据模型。

dev-master 2016-09-11 07:27 UTC

This package is not auto-updated.

Last update: 2024-09-28 19:47:30 UTC


README

Laravel MongoDB 的扩展 Laravel MongoDB

当数据保存到 MongoDB 时,数据将按照定义的架构进行格式化。当从 MongoModel 或 NestedMongoModel 实例检索数据时,数据将按照定义的架构进行转换,就像 Laravel Eloquent 所做的那样。

新的 NestedMongoModel 比数组更具表达力,请参阅以下介绍。

所有其他功能,如查询构建、关系等,与 Laravel Eloquent 的功能保持不变。

安装

使用 composer 安装

composer require suren/laravel-mongo-model-schema dev-master

从 MongoModel 扩展模型

use Suren\LaravelMongoModelSchema\MongoModel;

class User extends MongoModel


use Suren\LaravelMongoModelSchema\NestedMongoModel;

class Avatar extends NestedMongoModel

定义架构

覆盖 MongoModel 和 NestedMongoModel 中的 SCHEMAS 函数

public static function SCHEMAS()
{
    return [
        'integer_field' => ['type' => 'int',    'default' => 1],
        'float_field'   => ['type' => 'float',  'default' => 1.0],
        'string_field'  => ['type' => 'string', 'default' => 'default_string'],
        'bool_field'    => ['type' => 'bool',   'default' => false],
        'date_field'    => ['type' => 'date',   'default' => Carbon:now()],
        'time_field'    => ['type' => 'timestamp', 'default' => time()],
        'object_id_field'       => ['type' => ObjectID::class,      'default' => new ObjectId()],
        'nested_object_field'   => ['type' => NestedObject::class,  'default' => []],
        
        'integer_array_field'   => ['type' => 'array(int)',     'default' => [1, 2]],
        'float_array_field'     => ['type' => 'array(float)',   'default' => [1.0, 2.0]],
        'string_array_field'    => ['type' => 'array(string)',  'default' => ['default_string', 'another_string']],
        'bool_array_field'      => ['type' => 'array(bool)',    'default' => [true, false]],
        'date_array_field'      => ['type' => 'array(date)',    'default' => [Carbon:now(), Carbon:now()]],
        'time_array_field'      => ['type' => 'array(time)',    'default' => [time(), time()]],
        'object_id_array_field'     => ['type' => 'array(' . ObjectID::class . ')',     'default' => [new ObjectId(), new ObjectId()]],
        'nested_object_array_field' => ['type' => 'array(' . NestedObject::class . ')', 'default' => [[], new NestedObject()]],
    ];
}

架构

原始 Laravel 转换类型,如 array、object、json、collection 已被弃用。

ObjectId 类型将作为字符串保存在 MongoDB 中。

特定类型的数组将作为数组保存在 MongoDB 中,而不是 json 值。

架构中的默认字段指示在未为模型设置值时将检索哪个值。

NestedMongoModel

NestedMongoModel 将附加到其父对象中,而不是一个独立的文档。当保存到 MongoDB 时,它将被格式化为键值数组,并在从父对象检索时自动转换为定义的 NestedMongoModel。

也可以为 NestedMongoModel 定义架构。

您可以在 NestedMongoModel 内部定义另一个 NestedMongoModel。

支持批量赋值,就像 Eloquent 一样。

protected $fillable = ['width', 'height']; 

默认情况下,所有字段都将显示,可以通过定义可见和隐藏字段来控制此行为,就像 Eloquent 一样。

protected $visible = ['name', 'gender'];    // only these fields will show
protected $hidden = ['password', 'secret']; // these fields will be show

支持为 json_encode 添加字段,就像 Eloquent 一样。

protected $appends = ['is_admin'];

public function getIsAdminAttribute()
{
    return $this->role == self::ROLE_ADMIN;
}

示例

我们定义一个 User 模型和一个 Avatar 模型来存储用户的头像信息。

class User extends MongoModel
{
    const ROLE_STAFF = 1;
    const ROLE_ADMIN = 2;
    
    protected $fillable = ['name', 'role', 'avatar', 'password'];
    protected $hidden = ['password'];
    
    public static function SCHEMAS()
    {
        return [
            'name'      => ['type' => 'string'],
            'age'       => ['type' => 'int'],
            'role'      => ['type' => 'int', 'default' => self::ROLE_STAFF],
            'avatar'    => ['type' => Avatar::class, 'default' => new Avatar()],
            'password'  => ['type' => 'string'],
        ];
    }
}

class Avatar extends NestedMongoModel
{
    const SOURCE_UPLOAD         = 1;    // directly upload
    const SOURCE_THIRD_PARTY    = 2;    // get from third party account
    
    protected $visible = ['width', 'height'];
    protected $append = ['full_url'];
    
    public static function SCHEMAS()
    {
        return [
            'url'       => ['type' => 'string'],
            'width'     => ['type' => 'int'],
            'height'    => ['type' => 'int'],
            'source'    => ['type' => 'int'],
        ];
    }
    
    public function getFullUrlAttribute()
    {
        return 'http://hostname/' . $this->url;
    }
}

MongoModel 和它的 NestedMongoModel 可以这样创建。

$user = User::create([
    'name'  => 'Suren',
    'age'   => '30',
    'avatar' => new Avatar([
        'url' => 'saved_path',
        'width' => 100,
        'height' => 50,
    ]),
    'password' => 'secret',
]);

角色未定义,但它将被保存为 User::ROLE_STAFF,这是默认值。年龄将被保存为整数,尽管它被设置为字符串值。用户头像的来源将不会保存,因为它没有默认值。

JSON 编码结果。

$user = User::first();
echo json_encode($user, JSON_PRETTY_PRINT);

### json_encode result ###
{
    "name": "Suren",
    "age": 30,
    "role": 1,
    "avatar": {
        "width": 100,
        "height": 50,
        "full_url": "http://hostname/saved_path" 
    }
}