Laravel MongoDB 資料庫查詢擴充外掛 擴充原始 Laravel 類

OnlyDawn發表於2019-10-28

一個Eloquent模型和Query構建器,支援MongoDB,使用原始的Laravel API。該庫擴充套件了原始的Laravel類,因此它使用完全相同的方法。

安裝 Installation

確保安裝了MongoDB PHP驅動程式。您可以在 http://php.net/manual/en/mongodb.installation.php找到安裝說明

警告:版本> = 3.0時不再支援舊的mongo PHP驅動程式。

使用composer安裝:

composer require jenssegers/mongodb

Laravel版相容性

Laravel Package
4.2.x 2.0.x
5.0.x 2.1.x
5.1.x 2.2.x or 3.0.x
5.2.x 2.3.x or 3.0.x
5.3.x 3.1.x or 3.2.x
5.4.x 3.2.x
5.5.x 3.3.x
5.6.x 3.4.x

並新增服務提供商config/app.php

Jenssegers\Mongodb\MongodbServiceProvider::class,

要與Lumen一起使用,請新增服務提供商bootstrap/app.php。在此檔案中,您還需要啟用Eloquent。不過,你必須確保你的呼叫$app->withEloquent();是下面您已經註冊的,其中MongodbServiceProvider

$app->register(Jenssegers\Mongodb\MongodbServiceProvider::class);

$app->withEloquent();

服務提供者將使用原始資料庫管理器註冊mongodb資料庫擴充套件。無需註冊其他外牆或物體。使用mongodb連線時,Laravel會自動為您提供相應的mongodb物件。

要在Laravel外使用,請檢視Capsule管理器並新增:

$capsule->getDatabaseManager()->extend('mongodb', function($config)
{
    return new Jenssegers\Mongodb\Connection($config);
});

升級 Upgrading

從版本2升級到3

在這個支援新mongodb PHP擴充套件的新主要版本中,我們還移動了Model類的位置,並用特徵替換了MySQL模型類。

請更改所有模型頂部或註冊別名Jenssegers\Mongodb\Model為Jenssegers\Mongodb\Eloquent\Model

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {}

如果您使用混合關係,您的MySQL類現在應該擴充套件原始的Eloquent模型類Illuminate\Database\Eloquent\Model不是刪除Jenssegers\Eloquent\Model。而是使用新的Jenssegers\Mongodb\Eloquent\HybridRelations特性。這應該使事情更清楚,因為此包中只有一個單一的模型類。

use Jenssegers\Mongodb\Eloquent\HybridRelations;

class User extends Eloquent {

    use HybridRelations;

    protected $connection = 'mysql';

}

嵌入式關係現在返回一個Illuminate\Database\Eloquent\Collection而不是自定義Collection類。如果您使用的是一種可用的特殊方法,請將它們轉換為Collection集合操作。

$books = $user->books()->sortBy('title');

測試 Testing

要執行此程式包的測試,請執行:

docker-compose up

配置 Configuration

更改您的預設資料庫連線名稱config/database.php

'default' => env('DB_CONNECTION', 'mongodb'),

新增一個新的mongodb連線:

'mongodb' => [
    'driver'   => 'mongodb',
    'host'     => env('DB_HOST', 'localhost'),
    'port'     => env('DB_PORT', 27017),
    'database' => env('DB_DATABASE'),
    'username' => env('DB_USERNAME'),
    'password' => env('DB_PASSWORD'),
    'options'  => [
        'database' => 'admin' // sets the authentication database required by mongo 3
    ]
],

您可以使用以下配置連線到多個伺服器或副本集:

'mongodb' => [
    'driver'   => 'mongodb',
    'host'     => ['server1', 'server2'],
    'port'     => env('DB_PORT', 27017),
    'database' => env('DB_DATABASE'),
    'username' => env('DB_USERNAME'),
    'password' => env('DB_PASSWORD'),
    'options'  => [
        'replicaSet' => 'replicaSetName'
    ]
],

或者,您可以使用MongoDB連線字串:

'mongodb' => [
    'driver'   => 'mongodb',
    'dsn' => env('DB_DSN'),
    'database' => env('DB_DATABASE'),
],

有關其URI格式,請參閱MongoDB官方文件:https://docs.mongodb.com/manual/reference/...

Eloquent

該軟體包包括一個啟用MongoDB的Eloquent類,您可以使用它來定義相應集合的模型。

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {}

請注意,我們沒有告訴Eloquent哪個集合用於User模型。就像原始的Eloquent一樣,除非明確指定其他名稱,否則該類的小寫複數名稱將用作集合名稱。您可以透過collection在模型上定義屬性來指定自定義集合(表的別名):

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

    protected $collection = 'users_collection';

}

注意: Eloquent還假定每個集合都有一個名為id的主鍵列。您可以定義一個primaryKey屬性來覆蓋此約定。同樣,您可以定義一個connection屬性來覆蓋使用模型時應該使用的資料庫連線的名稱。

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class MyModel extends Eloquent {

    protected $connection = 'mongodb';

}

其他所有(應該)都像原始的Eloquent模型一樣工作。在http://learnku.com/docs/laravel/eloquent上閱讀有關Eloquent的更多資訊

可選項:別名 Alias

您還可以透過將以下內容新增到別名陣列中來註冊MongoDB模型的別名config/app.php

'Moloquent' => Jenssegers\Mongodb\Eloquent\Model::class,

這將允許您使用註冊的別名,如:

class MyModel extends Moloquent {}

查詢生成器 Query Builder

資料庫驅動程式直接插入原始查詢構建器。使用mongodb連線時,您將能夠構建流暢的查詢來執行資料庫操作。為方便起見,還有一個collection別名table以及一些額外的mongodb特定運算子/操作。

$users = DB::collection('users')->get();

$user = DB::collection('users')->where('name', 'John')->first();

如果未更改預設資料庫連線,則需要在查詢時指定它。

$user = DB::connection('mongodb')->collection('users')->get();

http://learnku.com/docs/laravel/queries上閱讀有關查詢構建器的更多資訊

構建器 Schema

資料庫驅動程式還具有(有限的)架構構建器支援。您可以輕鬆地操作集合並設定索引:

Schema::create('users', function($collection)
{
    $collection->index('name');

    $collection->unique('email');
});

支援的操作如下:

  • create 和 drop
  • collection
  • hasCollection
  • index 和 dropIndex (compound indexes supported as well)
  • unique
  • background, sparse, expire, geospatial (MongoDB specific)

所有其他(不支援的)操作都實現為虛擬傳遞方法,因為MongoDB不使用預定義的模式。在http://learnku.com/docs/laravel/schema上閱讀有關架構構建器的更多資訊

地理空間索引

2dsphere。使用模式構建器將這些新增到集合中。

Schema::create('users', function($collection)
{
    $collection->geospatial('name', '2d');
});

新增 2dsphere index:

Schema::create('users', function($collection)
{
    $collection->geospatial('name', '2dsphere');
});

擴充套件 Extensions

認證

如果您想使用Laravel的本機Auth功能,請註冊此包含的服務提供商:

'Jenssegers\Mongodb\Auth\PasswordResetServiceProvider',

此服務提供程式將稍微修改內部DatabaseReminderRepository以新增對基於MongoDB的密碼提醒的支援。如果您不使用密碼提醒,則無需註冊此服務提供商,其他一切都應該正常工作。

佇列

如果要將MongoDB用作資料庫後端,請更改以下驅動程式config/queue.php

'connections' => [
    'database' => [
        'driver' => 'mongodb',
        'table'  => 'jobs',
        'queue'  => 'default',
        'expire' => 60,
    ],

如果要使用MongoDB處理失敗的處理,請在config/queue.php以下位置更改資料庫:

'failed' => [
    'database' => 'mongodb',
    'table'    => 'failed_jobs',
    ],

並新增服務提供商config/app.php

Jenssegers\Mongodb\MongodbQueueServiceProvider::class,

Sentry

如果您想將此庫與 https://github.com/jenssegers/Laravel-Mong...

Sessions

MongoDB會話驅動程式在單獨的包中提供,請檢視 https://github.com/jenssegers/Laravel-Mong...

例子 Examples

基本用法

檢索所有模型

$users = User::all();

透過主鍵檢索記錄

$user = User::find('517c43667db388101e00000f');

Wheres

$users = User::where('votes', '>', 100)->take(10)->get();

Or Statements

$users = User::where('votes', '>', 100)->orWhere('name', 'John')->get();

And Statements

$users = User::where('votes', '>', 100)->where('name', '=', 'John')->get();

Using Where In With An Array

$users = User::whereIn('age', [16, 18, 20])->get();

whereNotIn如果欄位不存在,將返回使用物件。結合使用whereNotNull('age')可以省去這些檔案。
Using Where Between

$users = User::whereBetween('votes', [1, 100])->get();

Where null

$users = User::whereNull('updated_at')->get();

Order By

$users = User::orderBy('name', 'desc')->get();

Offset & Limit

$users = User::skip(10)->take(5)->get();

Distinct

Distinct需要一個欄位,可以返回不同的值。

$users = User::distinct()->get(['name']);
// or
$users = User::distinct('name')->get();

Distinct 結合 where 條件

$users = User::where('active', true)->distinct('name')->get();

自定義 Wheres

$users = User::where('name', '=', 'John')->orWhere(function($query)
    {
        $query->where('votes', '>', 100)
              ->where('title', '<>', 'Admin');
    })
    ->get();

Group By

$users = Users::groupBy('title')->get(['title', 'name']);

聚合查詢 Aggregation

聚合僅適用於大於2.2的MongoDB版本。

$total = Order::count();
$price = Order::max('price');
$price = Order::min('price');
$price = Order::avg('price');
$total = Order::sum('price');

聚合查詢與 where: 條件

$sold = Orders::where('sold', true)->sum('price');

聚合也可以用於:

$total = Order::max('suborder.price');
...

注意:此aggreagtion僅適用於單個子文件(如embedsOne)而非子文件陣列(如embedsMany)

Like

$user = Comment::where('body', 'like', '%spam%')->get();

遞增或遞減列的值

對指定的屬性執行增量或減量(預設值1):

User::where('name', 'John Doe')->increment('age');
User::where('name', 'Jaques')->decrement('weight', 50);

返回更新的物件數:

$count = User->increment('age');

您還可以指定要更新的其他列:

User::where('age', '29')->increment('age', 1, ['group' => 'thirty something']);
User::where('bmi', 30)->decrement('bmi', 1, ['category' => 'overweight']);

軟刪除

軟刪除模型時,實際上並未從資料庫中刪除它。而是在記錄上設定deleted_at時間戳。要為模型啟用軟刪除,請將SoftDeletingTrait應用於模型:

use Jenssegers\Mongodb\Eloquent\SoftDeletes;

class User extends Eloquent {

    use SoftDeletes;

    protected $dates = ['deleted_at'];

}

有關更多資訊,請訪問 http://learnku.com/docs/laravel/eloquent#soft-dele...

MongoDB特殊運算

exists

匹配具有指定欄位的文件。

User::where('age', 'exists', true)->get();

All

匹配包含查詢中指定的所有元素的陣列。

User::where('roles', 'all', ['moderator', 'author'])->get();

Size

如果陣列欄位是指定大小,則選擇文件。

User::where('tags', 'size', 3)->get();

Regex

選擇值與指定正規表示式匹配的文件。

User::where('name', 'regex', new \MongoDB\BSON\Regex("/.*doe/i"))->get();

注意:您還可以使用Laravel regexp操作。這些更靈活,會自動將正規表示式字串轉換為MongoDB \ BSON \ Regex物件。

User::where('name', 'regexp', '/.*doe/i'))->get();

反之:

User::where('name', 'not regexp', '/.*doe/i'))->get();

Type

如果欄位是指定型別,則選擇文件。有關更多資訊,請訪問: http://docs.mongodb.org/manual/reference/o...

User::where('age', 'type', 2)->get();

Mod

對欄位的值執行模運算,並選擇具有指定結果的文件。

User::where('age', 'mod', [10, 0])->get();

Near

注意:按此順序指定座標:longitude, latitude。

$users = User::where('location', 'near', [
    '$geometry' => [
        'type' => 'Point',
        'coordinates' => [
            -0.1367563,
            51.5100913,
        ],
    ],
    '$maxDistance' => 50,
]);

GeoWithin

$users = User::where('location', 'geoWithin', [
    '$geometry' => [
        'type' => 'Polygon',
        'coordinates' => [[
            [
                -0.1450383,
                51.5069158,
            ],       
            [
                -0.1367563,
                51.5100913,
            ],       
            [
                -0.1270247,
                51.5013233,
            ],  
            [
                -0.1450383,
                51.5069158,
            ],
        ]],
    ],
]);

GeoIntersects

$locations = Location::where('location', 'geoIntersects', [
    '$geometry' => [
        'type' => 'LineString',
        'coordinates' => [
            [
                -0.144044,
                51.515215,
            ],
            [
                -0.129545,
                51.507864,
            ],
        ],
    ],
]);

Where

匹配滿足JavaScript表示式的文件。有關更多資訊,請訪問 http://docs.mongodb.org/manual/reference/o...

插入,更新和刪除

插入,更新和刪除記錄就像原始的Eloquent一樣。

Saving a new model

$user = new User;
$user->name = 'John';
$user->save();

您還可以使用create方法將新模型儲存在一行中:

User::create(['name' => 'John']);

Updating a model

要更新模型,您可以檢索它,更改屬性並使用save方法。

$user = User::first();
$user->email = 'john@foo.com';
$user->save();

還有對upsert操作的支援,請檢視 https://github.com/jenssegers/laravel-mong...

Deleting a model

要刪除模型,只需在例項上呼叫delete方法:

$user = User::first();
$user->delete();

或者按鍵刪除模型:

User::destroy('517c43667db388101e00000f');

有關模型操作的更多資訊,請檢視 http://learnku.com/docs/laravel/eloquent#insert-up...

Dates

Eloquent允許您使用Carbon / DateTime物件而不是MongoDate物件。在內部,這些日期在儲存到資料庫時將轉換為MongoDate物件。如果您希望在非預設日期欄位上使用此功能,則需要按照此處所述手動指定它們: http://learnku.com/docs/laravel/eloquent#date-muta...

例:

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

    protected $dates = ['birthday'];

}

這允許您執行以下查詢:

$users = User::where('birthday', '>', new DateTime('-18 years'))->get();

Relations

支援的關係是:

  • hasOne
  • hasMany
  • belongsTo
  • belongsToMany
  • embedsOne
  • embedsMany

例:

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

    public function items()
    {
        return $this->hasMany('Item');
    }

}

歸屬關係:

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Item extends Eloquent {

    public function user()
    {
        return $this->belongsTo('User');
    }

}

belongsToMany關係不會使用資料透視表“table”,而是將id推送到related_ids屬性。這使belongsToMany方法的第二個引數無用。如果要為關係定義自定義鍵,請將其設定為null

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

    public function groups()
    {
        return $this->belongsToMany('Group', null, 'user_ids', 'group_ids');
    }

}

其他關係尚未得到支援,但可能會在未來新增。有關這些關係的更多資訊,請訪問 http://learnku.com/docs/laravel/eloquent#relations...

嵌入許多關係

如果要嵌入模型而不是引用模型,可以使用embedsMany關係。此關係類似於hasMany關係,但將模型嵌入父物件中。

記住:這些關係返回El​​oquent集合,它們不返回查詢構建器物件!

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

    public function books()
    {
        return $this->embedsMany('Book');
    }

}

您可以透過動態屬性訪問嵌入式模型:

$books = User::first()->books;

反向關係是自動神奇可用的,您不需要定義此歸屬關係。

$user = $book->user;

插入和更新嵌入式模型的工作方式類似於以下hasMany關係:

$book = new Book(['title' => 'A Game of Thrones']);

$user = User::first();

$book = $user->books()->save($book);
// or
$book = $user->books()->create(['title' => 'A Game of Thrones'])

您可以使用他們的save方法更新嵌入式模型(從2.0.0版開始提供):

$book = $user->books()->first();

$book->title = 'A Game of Thrones';

$book->save();

您可以使用destroy關係上的delete方法或模型上的方法(從2.0.0版開始提供)來刪除嵌入式模型:

$book = $user->books()->first();

$book->delete();
// or
$user->books()->destroy($book);

如果要在不觸及資料庫的情況下新增或刪除嵌入式模型,可以使用associatedissociate方法。要最終將更改寫入資料庫,請儲存父物件:

$user->books()->associate($book);

$user->save();

與其他關係一樣,embedsMany根據模型名稱假定關係的本地鍵。您可以透過將第二個引數傳遞給embedsMany方法來覆蓋預設本地鍵:

return $this->embedsMany('Book', 'local_key');

嵌入式關係將返回嵌入項的集合,而不是查詢構建器。檢視可用的操作: https://learnku.com/docs/laravel/master/collection...

EmbedsOne Relations

embedsOne關係類似於EmbedsMany關係,但只嵌入單個模型。

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Book extends Eloquent {

    public function author()
    {
        return $this->embedsOne('Author');
    }

}

您可以透過動態屬性訪問嵌入式模型:

$author = Book::first()->author;

插入和更新嵌入式模型的工作方式類似於以下hasOne關係:

$author = new Author(['name' => 'John Doe']);

$book = Books::first();

$author = $book->author()->save($author);
// or
$author = $book->author()->create(['name' => 'John Doe']);

您可以使用該save方法更新嵌入式模型(從2.0.0版開始提供):

$author = $book->author;

$author->name = 'Jane Doe';
$author->save();

您可以使用以下新模型替換嵌入式模型:

$newAuthor = new Author(['name' => 'Jane Doe']);
$book->author()->save($newAuthor);

與 MySQL 相關的資訊

如果你正在使用混合的MongoDB和SQL設定,那麼你很幸運!模型將根據相關模型的型別自動返回MongoDB或SQL關係。當然,如果您希望此功能同時工作,那麼您的SQL模型將需要使用該Jenssegers\Mongodb\Eloquent\HybridRelations特徵。請注意,此功能僅適用於hasOne,hasMany和belongsTo關係。

示例基於SQL的使用者模型:

use Jenssegers\Mongodb\Eloquent\HybridRelations;

class User extends Eloquent {

    use HybridRelations;

    protected $connection = 'mysql';

    public function messages()
    {
        return $this->hasMany('Message');
    }

}

而基於Mongodb的Message模型:

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Message extends Eloquent {

    protected $connection = 'mongodb';

    public function user()
    {
        return $this->belongsTo('User');
    }

}

原始表示式

這些表示式將直接注入查詢中。

User::whereRaw(['age' => array('$gt' => 30, '$lt' => 40)])->get();

您還可以在內部MongoCollection物件上執行原始表示式。如果在模型類上執行此操作,它將返回一組模型。如果在查詢構建器上執行此操作,它將返回原始響應。

// Returns a collection of User models.
$models = User::raw(function($collection)
{
    return $collection->find();
});

// Returns the original MongoCursor.
$cursor = DB::collection('users')->raw(function($collection)
{
    return $collection->find();
});

可選:如果未將閉包傳遞給raw方法,則可以訪問內部MongoCollection物件:

$model = User::raw()->findOne(['age' => array('$lt' => 18)]);

可以像這樣訪問內部MongoClient和MongoDB物件:

$client = DB::getMongoClient();
$db = DB::getMongoDB();

MongoDB的具體操作

遊標超時

要防止MongoCursorTimeout異常,您可以手動設定將應用於遊標的超時值:

DB::collection('users')->timeout(-1)->get();

Upsert

更新或插入文件。update方法的其他選項將直接傳遞給本機更新方法。

DB::collection('users')->where('name', 'John')
                       ->update($data, ['upsert' => true]);

Projections

您可以使用該project方法將投影應用於查詢。

DB::collection('items')->project(['tags' => ['$slice' => 1]])->get();
DB::collection('items')->project(['tags' => ['$slice' => [3, 7]]])->get();

Projections with Pagination

$limit = 25;
$projections = ['id', 'name'];
DB::collection('items')->paginate($limit, $projections);

Push

將單項新增到陣列。

DB::collection('users')->where('name', 'John')->push('items', 'boots');
DB::collection('users')->where('name', 'John')->push('messages', ['from' => 'Jane Doe', 'message' => 'Hi John']);

如果您不想要重複項,請將第三個引數設定為true:

DB::collection('users')->where('name', 'John')->push('items', 'boots', true);

Pull

從陣列中刪除專案。

DB::collection('users')->where('name', 'John')->pull('items', 'boots');
DB::collection('users')->where('name', 'John')->pull('messages', ['from' => 'Jane Doe', 'message' => 'Hi John']);

Unset

從文件中刪除一個或多個欄位。

DB::collection('users')->where('name', 'John')->unset('note');

您還可以在模型上執行取消設定。

$user = User::where('name', 'John')->first();
$user->unset('note');

查詢快取 Query Caching

您可以使用remember方法輕鬆快取查詢結果:

$users = User::remember(10)->get();

來自: http://learnku.com/docs/laravel/queries#caching-qu...
查詢日誌 Query Logging

預設情況下,Laravel會記錄已為當前請求執行的所有查詢的記憶體。但是,在某些情況下,例如插入大量行時,這可能會導致應用程式使用過多的記憶體。要禁用日誌,您可以使用以下disableQueryLog方法:

DB::connection()->disableQueryLog();

來自:http://learnku.com/docs/laravel/database#query-log...

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章