laravel MongoDB 的使用

MongoDB 條件操作符

Exists(判斷字段是否存在)

查詢(xún)所有存在age字段的記錄

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

查詢(xún)所有不存在name字段的記錄

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

All(匹配所有)

這個(gè)操作符跟SQL語(yǔ)法的in類(lèi)似,但不同的是, in只需滿(mǎn)足( )內(nèi)的某一個(gè)值即可,而$all必須滿(mǎn)足[ ]內(nèi)的所有值

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

Size(數(shù)組元素個(gè)數(shù))

對(duì)于查詢(xún)數(shù)組來(lái)說(shuō)是非常有用的,顧名思義,可以用它查詢(xún)特定長(zhǎng)度的數(shù)組。

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

Regex(正則表達(dá)式匹配)

選擇值與指定正則表達(dá)式匹配的文檔。

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

注意:您也可以使用Laravel正則表達(dá)式操作。 這些更靈活,會(huì)自動(dòng)將正則表達(dá)式字符串轉(zhuǎn)換為MongoDB \ BSON \ Regex對(duì)象。

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

反之:

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

Type(類(lèi)型)

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

Mod(取模運(yùn)算)

查詢(xún)age取模10等于0的數(shù)據(jù)

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

Near(指定地理空間查詢(xún)從最近到最遠(yuǎn)返回文檔的點(diǎn)。)

$ near運(yùn)算符可以指定GeoJSON點(diǎn)或傳統(tǒng)坐標(biāo)點(diǎn)。

$users = User::where('location', 'near', [

????????'$geometry' => [

????????'type' => 'Point',

????????'coordinates' => [

????????????????-0.1367563,

????????????????51.5100913,

????????????],

????????],

????????'$maxDistance' => 50,

]);

GeoWithin(選擇具有完全在指定形狀內(nèi)的地理空間數(shù)據(jù)的文檔。)

$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(選擇地理空間數(shù)據(jù)與指定GeoJSON對(duì)象相交的文檔;即數(shù)據(jù)和指定對(duì)象的交集是非空的。)

$locations = Location::where('location', 'geoIntersects', [

'$geometry' => [

????????'type' => 'LineString',

????????'coordinates' => [

????????????[-0.144044,51.515215,],[-0.129545,51.507864,],

????????],

????????],

????]);

Where

匹配滿(mǎn)足JavaScript表達(dá)式的文檔。 有關(guān)更多信息,請(qǐng)查看 http://docs.mongodb.org/manual/reference/operator/query/where/#op._S_where

Inserts, updates and deletes

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

通過(guò)模型插入數(shù)據(jù)

$user = new User;

$user->name = 'John';

$user->save();

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

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

通過(guò)模型更新數(shù)據(jù)

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

$user = User::first();

$user->email = 'john@foo.com';

$user->save();

通過(guò)模型刪除數(shù)據(jù)

要?jiǎng)h除模型,只需在實(shí)例上調(diào)用delete方法:

$user = User::first();

$user->delete();

或者通過(guò)主鍵刪除

User::destroy('517c43667db388101e00000f');

Dates

Eloquent允許您使用Carbon / DateTime對(duì)象而不是MongoDate對(duì)象。 在內(nèi)部,這些日期在保存到數(shù)據(jù)庫(kù)時(shí)將轉(zhuǎn)換為MongoDate對(duì)象。 如果您希望在非默認(rèn)日期字段中使用此功能,則需要按照此處所述手動(dòng)指定它們:http://laravel.com/docs/eloquent#date-mutators

示例:

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

protected $dates = ['birthday'];

}

Which allows you to execute queries like:

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

MongoDB 關(guān)系

MongoDB的關(guān)系表示多個(gè)文檔之間在邏輯上的相互聯(lián)系文檔間可以通過(guò)嵌入和引用來(lái)建立聯(lián)系。

支持的關(guān)系有:

* hasOne

* hasMany

* belongsTo

* belongsToMany

* embedsOne

* embedsMany

示例:

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

public function items(){

????return $this->hasMany('Item');

????}

}

和反比關(guān)系:

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Item extends Eloquent {

public function user(){

????return $this->belongsTo('User');

????}

}

belongsToMany關(guān)系不會(huì)使用數(shù)據(jù)透視表“table”,而是將id推送到related_ids屬性。 這使belongsToMany方法的第二個(gè)參數(shù)無(wú)用。 如果要為關(guān)系定義自定義鍵,請(qǐng)將其設(shè)置為null:

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

public function groups(){

????return $this->belongsToMany('Group', null, 'user_ids', 'group_ids');

????}

}

其他關(guān)系尚未得到支持,但未來(lái)可能會(huì)增加。 在http://laravel.com/docs/eloquent#relationships上閱讀有關(guān)這些關(guān)系的更多信息

EmbedsMany Relations

如果要嵌入模型而不是引用它們,可以使用embedsMany關(guān)系。 此關(guān)系類(lèi)似于hasMany關(guān)系,但將模型嵌入父對(duì)象中。

記住:這些關(guān)系返回Eloquent集合,它們不返回查詢(xún)構(gòu)建器對(duì)象!

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class User extends Eloquent {

public function books(){

????return $this->embedsMany('Book');

????}

}

您可以通過(guò)動(dòng)態(tài)屬性訪(fǎng)問(wèn)嵌入式模型:

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

反向關(guān)系是自動(dòng)可用的,您無(wú)需定義此反向關(guān)系。

$user = $book->user;

插入和更新嵌入式模型的工作方式與hasMany關(guān)系類(lèi)似:

$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'])

您可以使用其保存方法更新嵌入式模型(從2.0.0版開(kāi)始提供):

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

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

$book->save();

您可以通過(guò)在關(guān)系上使用destroy方法或模型上的delete方法(從2.0.0版開(kāi)始提供)來(lái)刪除嵌入式模型:

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

$book->delete();

// or

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

如果要在不觸及數(shù)據(jù)庫(kù)的情況下添加或刪除嵌入式模型,可以使用關(guān)聯(lián)和分離方法。 要最終將更改寫(xiě)入數(shù)據(jù)庫(kù),請(qǐng)保存父對(duì)象:

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

$user->save();

與其他關(guān)系一樣,embedsMany根據(jù)模型名稱(chēng)假定關(guān)系的本地鍵。 您可以通過(guò)將第二個(gè)參數(shù)傳遞給embedsMany方法來(lái)覆蓋默認(rèn)本地鍵:

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

嵌入式關(guān)系將返回嵌入式項(xiàng)的集合,而不是查詢(xún)構(gòu)建器。 查看可用的操作:https://laravel.com/docs/master/collections

EmbedsOne Relations

embedsOne關(guān)系類(lèi)似于embedsMany關(guān)系,但只嵌入單個(gè)模型。

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Book extends Eloquent {

public function author(){

????return $this->embedsOne('Author');

????}

}

您可以通過(guò)動(dòng)態(tài)屬性訪(fǎng)問(wèn)嵌入式模型:

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

插入和更新嵌入式模型的工作方式與hasOne關(guān)系類(lèi)似:

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

$book = Books::first();

$author = $book->author()->save($author);

// or

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

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

$author = $book->author;

$author->name = 'Jane Doe';

$author->save();

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

$newAuthor = new Author(['name' => 'Jane Doe']);

$book->author()->save($newAuthor);

MySQL關(guān)系

如果您正在使用混合MongoDB和SQL設(shè)置,那么您很幸運(yùn)! 模型將根據(jù)相關(guān)模型的類(lèi)型自動(dòng)返回MongoDB或SQL關(guān)系。 當(dāng)然,如果您希望此功能雙向工作,則您的SQL模型將需要使用Jenssegers \ Mongodb \ Eloquent \ HybridRelations特性。 請(qǐng)注意,此功能僅適用于hasOne,hasMany和belongsTo關(guān)系。

示例基于SQL的用戶(hù)模型:

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');

????}

}

原始表達(dá)

這些表達(dá)式將直接注入查詢(xún)中。

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

您還可以在內(nèi)部MongoCollection對(duì)象上執(zhí)行原始表達(dá)式。 如果在模型類(lèi)上執(zhí)行此操作,它將返回一組模型。 如果在查詢(xún)構(gòu)建器上執(zhí)行此操作,它將返回原始響應(yīng)。

//返回用戶(hù)模型的集合。

$models = User::raw(function($collection){

????return $collection->find();

});

//返回原始的MongoCursor。

$cursor = DB::collection('users')->raw(function($collection){

????return $collection->find();

});

可選:如果未將閉包傳遞給raw方法,則可以訪(fǎng)問(wèn)內(nèi)部MongoCollection對(duì)象:

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

可以像這樣訪(fǎng)問(wèn)內(nèi)部MongoClient和MongoDB對(duì)象:

$client = DB::getMongoClient();

$db = DB::getMongoDB();

MongoDB 具體操作

超時(shí)

要防止MongoCursorTimeout異常,您可以手動(dòng)設(shè)置將應(yīng)用于游標(biāo)的超時(shí)值:

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

Upsert是一種特殊的更新方式,要是沒(méi)有找到符合條件的文檔,則會(huì)自動(dòng)創(chuàng)建一個(gè)文檔,否則更新對(duì)應(yīng)的文檔數(shù)據(jù)。

看 mongodb權(quán)威指南提到 upsert會(huì)避免競(jìng)態(tài)問(wèn)題,如果使用日常的思維去考慮這個(gè)問(wèn)題,需要先去數(shù)據(jù)庫(kù)中查找符合條件的文檔,然后再根據(jù)更新信息更新數(shù)據(jù),這個(gè)在多線(xiàn)程或者多進(jìn)程的情況下產(chǎn)生資源競(jìng)爭(zhēng)的情況,使用 upsert可以很好的避免這種情況的發(fā)

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

->update($data, ['upsert' => true]);

Projections(投影文檔)

您可以使用項(xiàng)目方法將投影應(yīng)用于查詢(xún)。

value字段的取值為0或者false時(shí),表示要在返回結(jié)果中去除該字段;如果value字段取值為1或者true,表示在返回結(jié)果中需要包含這個(gè)字段。

查詢(xún)結(jié)構(gòu)只展示title和likes

$project = ['title'=>1,'likes'=>1,"_id"=>0];

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

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

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

分頁(yè)使用

$limit = 25;

$projections = ['id', 'name'];

DB::collection('items')->paginate($limit, $projections);

Push(更新數(shù)組$push操作符)

$push操作符添加指定的值到數(shù)組中,$push操作符有如下的格式:

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

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

如果您不想要重復(fù)項(xiàng),請(qǐng)將第三個(gè)參數(shù)設(shè)置為true:

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

Pull(更新數(shù)組$pull修飾符)

$pull修飾符會(huì)刪除掉數(shù)組中符合條件的元素

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

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

Unset(刪除一個(gè)指定的字段)

如果指定的字段不存在則操作不做任何處理;

當(dāng)使用$操作符匹配任何數(shù)組元素,$unset替換指定的元素為null而不是刪除掉指定的元素,此行為保持?jǐn)?shù)組大小和位置一直;

從文檔中刪除一個(gè)或多個(gè)字段。

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

您還可以在模型上執(zhí)行取消設(shè)置。

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

$user->unset('note');

查詢(xún)緩存

您可以使用remember方法輕松緩存查詢(xún)結(jié)果:

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

參考: http://laravel.com/docs/queries#caching-queries

查詢(xún)記錄

默認(rèn)情況下,Laravel會(huì)記錄已為當(dāng)前請(qǐng)求運(yùn)行的所有查詢(xún)的內(nèi)存。 但是,在某些情況下,例如插入大量行時(shí),這可能會(huì)導(dǎo)致應(yīng)用程序使用過(guò)多的內(nèi)存。 要禁用日志,可以使用disableQueryLog方法:

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,362評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,013評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 177,346評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,421評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,146評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,534評(píng)論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,585評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,767評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,318評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,074評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,258評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,828評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,486評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,916評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,156評(píng)論 1 290
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,993評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,234評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容