写入操作
在此页面上
Overview
在本指南中,您可以了解如何使用 Laravel MongoDB 对 MongoDB 集合执行写入操作。 写入操作包括根据指定条件插入、更新和删除数据。
本指南介绍如何执行以下任务:
示例模型
本指南中的写入操作引用了以下 Eloquent 模型类:
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Concert extends Model { protected $connection = 'mongodb'; protected $fillable = ['performer', 'venue', 'genres', 'ticketsSold', 'performanceDate']; protected $casts = ['performanceDate' => 'datetime']; }
插入文档
在本节中,您可以学习;了解如何使用 Laravel MongoDB从 Laravel应用程序将文档插入到MongoDB集合中。
插入文档时,请确保数据不违反集合上的任何唯一索引。 插入集合的第一个文档或创建新集合时,MongoDB 会自动在_id
字段上创建唯一索引。
有关使用 Laravel 模式构建器在 MongoDB 集合上创建索引的更多信息,请参阅模式构建器文档的管理索引部分。
要学习;了解有关 Laravel 集成中的 Eloquent 模型的更多信息,请参阅 Eloquent模型部分。
插入文档示例
这些示例展示了如何使用save()
Eloquent 方法将Concert
模型的实例作为 MongoDB 文档插入。
当save()
方法成功时,您可以访问权限调用该方法的模型实例。
如果操作失败,则会为模型实例分配null
。
此示例代码执行以下操作:
创建
Concert
模型的新实例为
performer
和venue
字段分配string值将字符串数组赋值给
genre
字段为
ticketsSold
字段分配一个数字使用
Carbon
包为performanceDate
字段分配日期通过调用
save()
方法插入文档
$concert = new Concert(); $concert->performer = 'Mitsuko Uchida'; $concert->venue = 'Carnegie Hall'; $concert->genres = ['classical']; $concert->ticketsSold = 2121; $concert->performanceDate = Carbon::create(2024, 4, 1, 20, 0, 0, 'EST'); $concert->save();
您可以通过访问模型的id
成员来检索插入文档的_id
值,如以下代码示例所示:
$insertedId = $concert->id;
如果通过定义$fillable
或$guarded
属性来启用批量分配,则可以使用 Eloquent 模型的create()
方法在单次调用中执行插入,如以下示例所示:
$insertResult = Concert::create([ 'performer' => 'The Rolling Stones', 'venue' => 'Soldier Field', 'genres' => [ 'rock', 'pop', 'blues' ], 'ticketsSold' => 59527, 'performanceDate' => Carbon::create(2024, 6, 30, 20, 0, 0, 'CDT'), ]);
要了解有关CarbonPHPAPI 扩展的更多信息,请参阅 CarbonGithub 存储库。
插入多个文档示例
此示例演示如何使用insert()
Eloquent 方法将Concert
模型的多个实例作为MongoDB文档插入。 这种批量插入方法减少了应用程序为保存文档所需进行的调用次数。
当insert()
方法成功时,将返回值1
。
如果失败,则会引发异常。
示例代码将多个模型作为数组传递给insert()
方法,从而在一次调用中保存多个模型:
注意
此示例将日期包装在 MongoDB\BSON\UTCDateTime 类以将其转换为 MongoDB 可以序列化的类型,因为 Laravel 在批量插入操作上会跳过属性转换。
$data = [ [ 'performer' => 'Brad Mehldau', 'venue' => 'Philharmonie de Paris', 'genres' => [ 'jazz', 'post-bop' ], 'ticketsSold' => 5745, 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), ], [ 'performer' => 'Billy Joel', 'venue' => 'Madison Square Garden', 'genres' => [ 'rock', 'soft rock', 'pop rock' ], 'ticketsSold' => 12852, 'performanceDate' => new UTCDateTime(Carbon::create(2025, 2, 12, 20, 0, 0, 'CET')), ], ]; Concert::insert($data);
修改文档
在本节中,您可以了解如何从 Laravel 应用程序修改 MongoDB 集合中的文档。 使用更新操作修改现有文档,如果没有文档与Atlas Search条件匹配,则插入文档。
您可以保留对 Eloquent 模型实例的更改,或使用 Eloquent 的流式语法对返回 Laravel 集合对象的方法链接更新操作。
本部分提供了以下更新操作的示例:
更新文档示例
您可以通过以下方式更新文档:
修改模型实例,并通过调用
save()
方法保存更改。用于检索模型实例并通过调用
update()
方法对其执行更新的链式方法。
以下示例展示了如何通过修改模型实例并调用其save()
方法来更新文档:
$concert = Concert::first(); $concert->venue = 'Manchester Arena'; $concert->ticketsSold = 9543; $concert->save();
当save()
方法成功时,调用该方法的模型实例将包含更新的值。
如果操作失败,Laravel 集成将为模型实例分配null
值。
以下示例展示了如何通过链接检索和更新第一个匹配文档的方法来更新文档:
$concert = Concert::where(['performer' => 'Brad Mehldau']) ->orderBy('_id') ->first() ->update(['venue' => 'Manchester Arena', 'ticketsSold' => 9543]);
当update()
方法成功时,该操作将返回已更新的文档数。
如果调用的检索部分与任何文档都不匹配,Laravel 集成将返回以下错误:
Error: Call to a member function update() on null
更新多个文档示例
要对一个或多个文档执行更新,请将update()
方法链接到将文档检索为 Laravel 集合对象的方法的结果,例如where()
。
以下示例展示了如何链式调用以检索和更新匹配文档:
Concert::whereIn('venue', ['Philharmonie de Paris', 'Soldier Field']) ->update(['venue' => 'Concertgebouw', 'ticketsSold' => 0]);
当update()
方法成功时,该操作将返回已更新的文档数。
如果调用的检索部分与集合中的任何文档都不匹配,则 Laravel 集成将返回以下错误:
Error: Call to a member function update() on null
在单个操作中更新或插入
更新或插入操作允许您在单个操作中执行更新或插入。 此操作简化了更新文档或插入不存在文档的任务。
从 v 4.7开始, 您可以使用以下任一方法执行更新或更新或插入(upsert)操作:
upsert()
:使用此方法时,您可以执行批处理更新或插入(upsert)或插入,以便在一次操作中更改或插入多个文档。update()
:使用此方法时,必须指定upsert
选项以更新与查询过滤匹配的所有文档,如果没有文档匹配,则插入一个文档。 版本 v 4.6及更早版本仅支持此更新或更新或插入(upsert)方法。
更新或插入方法
upsert(array $values, array|string $uniqueBy, array|null
$update)
方法接受以下参数:
$values
:指定要更新或插入的文档的字段和值的数组。$uniqueBy
:唯一标识第一个大量参数中的文档的字段列表。$update
:存在匹配文档时要更新的可选字段列表。 如果省略此参数,Laravel 集成将更新所有字段。
要在upsert()
方法中指定更新或插入(upsert)或插入,请按以下代码示例所示设立参数:
YourModel::upsert( [/* documents to update or insert */], '/* unique field */', [/* fields to update */], );
例子
此示例演示如何使用upsert()
方法在单个操作中执行更新或插入。 单击 VIEW OUTPUT按钮以查看当集合中已存在performer
值为'Angel
Olsen'
的文档时产生的数据更改:
Concert::upsert([ ['performer' => 'Angel Olsen', 'venue' => 'Academy of Music', 'ticketsSold' => 275], ['performer' => 'Darondo', 'venue' => 'Cafe du Nord', 'ticketsSold' => 300], ], 'performer', ['ticketsSold']);
{ "_id": "...", "performer": "Angel Olsen", "venue": "State Theatre", "genres": [ "indie", "rock" ], "ticketsSold": 275, "updated_at": ... }, { "_id": "...", "performer": "Darondo", "venue": "Cafe du Nord", "ticketsSold": 300, "updated_at": ... }
在performer
值为'Angel
Olsen'
的文档中, venue
字段值不会更新,因为更新或更新或插入(upsert)操作指定更新仅适用于ticketsSold
字段。
更新方法
要在update()
方法中指定更新或插入,请将upsert
选项设置为true
,如以下代码示例所示:
YourModel::where(/* match criteria */) ->update( [/* update data */], ['upsert' => true]);
当update()
方法链接到查询时,它会执行以下操作之一:
如果查询与文档匹配,则
update()
方法会修改匹配的文档。如果查询匹配零个文档,则
update()
方法将插入一个包含更新数据和等值匹配条件数据的文档。
例子
此示例演示如何将upsert
选项传递给update()
方法以在单个操作中执行更新或插入。 单击VIEW OUTPUT按钮可查看在不存在匹配文档时插入的示例文档:
Concert::where(['performer' => 'Jon Batiste', 'venue' => 'Radio City Music Hall']) ->update( ['genres' => ['R&B', 'soul'], 'ticketsSold' => 4000], ['upsert' => true], );
{ "_id": "660c...", "performer": "Jon Batiste", "venue": "Radio City Music Hall", "genres": [ "R&B", "soul" ], "ticketsSold": 4000, "updated_at": ... }
更新文档中的数组
在本节中,您可以查看在 MongoDB 文档中更新数组值的以下操作示例:
这些示例修改通过以下插入操作创建的示例文档:
Concert::create([ 'performer' => 'Mitsuko Uchida', 'genres' => ['classical', 'dance-pop'], ]);
向数组添加值示例
本部分介绍如何使用push()
方法向 MongoDB 文档中的数组添加值。 您可以传递一个或多个要添加的值,并将可选参数unique
设置为true
,以跳过在数组中添加任何重复值的过程。 以下代码示例显示了push()
方法调用的结构:
YourModel::where(<match criteria>) ->push( <field name>, [<values>], // array or single value to add unique: true); // whether to skip existing values
以下示例演示如何将值"baroque"
添加到匹配文档的genres
数组字段。 单击VIEW OUTPUT按钮查看更新后的文档:
Concert::where('performer', 'Mitsuko Uchida') ->push( 'genres', ['baroque'], );
{ "_id": "660eb...", "performer": "Mitsuko Uchida", "genres": [ "classical", "dance-pop", ], "updated_at": ..., "created_at": ... }
从数组中删除值示例
本部分介绍如何使用pull()
方法从 MongoDB 文档的数组中删除值。 您可以传递一个或多个要从数组中删除的值。 以下代码示例显示了pull()
方法调用的结构:
YourModel::where(<match criteria>) ->pull( <field name>, [<values>]); // array or single value to remove
以下示例演示如何从genres
数组字段中删除数组值"classical"
和"dance-pop"
。 单击VIEW OUTPUT按钮查看更新后的文档:
Concert::where('performer', 'Mitsuko Uchida') ->pull( 'genres', ['dance-pop', 'classical'], );
{ "_id": "660e...", "performer": "Mitsuko Uchida", "genres": [], "updated_at": ..., "created_at": ... }
更新数组元素值示例
本部分介绍如何使用$
位置运算符更新 MongoDB 文档中的特定数组元素。 $
操作符表示与查询匹配的第一个数组元素。 以下代码示例显示了对单个匹配文档进行位置操作符更新调用的结构:
注意
目前,Laravel 集成仅在DB
门面上提供此操作,而不是在 Eloquent ORM 上提供此操作。
DB::connection('mongodb') ->getCollection(<collection name>) ->updateOne( <match criteria>, ['$set' => ['<array field>.$' => <replacement value>]]);
以下示例演示如何在genres
数组字段中将数组值"dance-pop"
替换为"contemporary"
。 单击VIEW OUTPUT按钮查看更新后的文档:
$match = ['performer' => 'Mitsuko Uchida', 'genres' => 'dance-pop']; $update = ['$set' => ['genres.$' => 'contemporary']]; DB::connection('mongodb') ->getCollection('concerts') ->updateOne($match, $update);
{ "_id": "660e...", "performer": "Mitsuko Uchida", "genres": [ "classical", "contemporary" ], "updated_at": ..., "created_at": ... }
Delete Documents
在本节中,您可以学习;了解如何使用 Laravel 集成从MongoDB集合中删除文档。 使用删除操作从MongoDB 数据库中删除数据。
本部分举例说明了以下删除操作:
要学习;了解Laravel 集成中提供的修改删除行为的 Laravel 功能,请参阅以下部分:
删除文档示例
您可以通过以下方式删除一个文档:
对模型的实例调用
$model->delete()
方法。在模型上调用
Model::destroy($id)
方法,向其传递要删除的文档的 ID。通过调用
delete()
方法来检索和删除模型实例的链式方法。
以下示例展示了如何通过对该模型的实例调用$model->delete()
来删除文档:
$concert = Concert::first(); $concert->delete();
当delete()
方法成功时,该操作将返回已删除的文档数。
如果调用的检索部分与集合中的任何文档都不匹配,则该操作将返回0
。
以下示例展示了如何通过将文档 ID 的值传递给Model::destroy($id)
方法来删除除文档:
$id = 'MSG-0212252000'; Concert::destroy($id);
当destroy()
方法成功时,它会返回已删除的文档数。
如果ID值与任何文档都不匹配,则 destroy()
方法返回 0
。
以下示例展示了如何链式调用以检索第一个匹配文档并将其删除:
Concert::where('venue', 'Carnegie Hall') ->limit(1) ->delete();
当delete()
方法成功时,它会返回已删除的文档数。
如果where()
方法未匹配任何文档, delete()
方法将返回0
。
删除多个文档示例
您可以通过以下方式删除多个文档:
调用
Model::destroy($ids)
方法,传递要删除的文档或模型实例的 ID 列表。链式方法以检索引用多个对象的 Laravel 集合对象,并通过调用
delete()
方法删除它们。
以下示例展示了如何通过将由 $ids
表示的ID值大量传递给 destroy()
方法来删除除文档:
$ids = [3, 5, 7, 9]; Concert::destroy($ids);
提示
传递大型列表时, destroy()
方法性能会受到影响。 为了获得更好的性能,请改用Model::whereIn('id', $ids)->delete()
。
当destroy()
方法成功时,它会返回已删除的文档数。
如果 ID 值与任何文档都不匹配,则destroy()
方法返回0
。
以下示例展示了如何链式调用以检索匹配的文档并将其删除:
Concert::where('ticketsSold', '>', 7500) ->delete();
当delete()
方法成功时,它会返回已删除的文档数。
如果where()
方法未匹配任何文档, delete()
方法将返回0
。