Laravel + MongoDB + jensseger/laravel-mongodb: update deeply nested mongodb documents

updated: 2022/3/29

 

環境:

laravel@7.28.4

mongodb-php-driver@1.7

jensseger/laravel-mongodb@3.7.0

 

編集したいprofielDetail model のstructureは下記とする。

Userモデルは一つのProfileDetailモデル(hasOne)を持つ。

hasOneModel では protected $fillable で update したい document をあらかじめ指定しなくてもよい。

f:id:monteecristoo:20201202092036p:plain

* phoneNumber, realName, birthDateはネストされた値を持ち, postalCodeはネストされていないため処理の分岐が必要。

 

$user = Auth::user();

$user->profileDetail()->update($request->input(), ['upsert'] => true);

f:id:monteecristoo:20201202094059p:plain

上記のリクエストでupdateするとbirthDate.y, birthDate.d, realName.lastName ごと上書きされて消失する。

github.com

qiita.com



solution)

f:id:monteecristoo:20201202094512p:plain

連想配列はドットでチェーンさせてあげる。

ネスト混在を分岐対応させた場合は下記

f:id:monteecristoo:20201202094906p:plain

github.com

solution2)

mongoDB php driver のメソッドを使う

$user->profileDetail()->raw()->updateOne(['user_id' => $user->id], ['$set' => ['phoneNumber.phoneNumber_1' => 333]], ['upsert' => true]);

laravel.com

docs.mongodb.com

 

追記

hasMany relationship では protected $fillable で登録しておく必要がある。

例えば、 user model が order model を複数持つ場合、

shippingInfo.address 等々、ネストされた想定されるドキュメントをあらかじめ protected $fillable に登録

User::first()->orders()->whrere(QUERY)->update(['shippingInfo.address' => 'newValue']);