Docs 菜单

修改文档

在本指南中,您可以学习;了解如何使用 Laravel MongoDB从 Laravel应用程序修改MongoDB集合中的文档。使用更新操作修改现有文档,或者如果没有与搜索条件匹配的文档,则插入文档。

您可以保留对 Eloquent 模型实例的更改,或使用 Eloquent 的流式语法对返回 Laravel 集合对象的方法链接更新操作。

本指南提供了以下更新操作的示例:

本指南中的操作引用了以下 Eloquent 模型类:

Community.php
<?php
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'];
}

提示

$fillable属性允许您对插入操作使用 Laravel 批量分配。 要学习;了解有关批量分配的更多信息,请参阅 Eloquent 模型类文档中的自定义批量分配

$casts属性指示 Laravel 将属性转换为常见数据类型。 要了解更多信息,请参阅 属性转换 在 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]);

注意

orderBy()调用按_id字段对结果进行排序,以保证排序顺序的一致性。 要了解有关MongoDB 排序的更多信息,请参阅 MongoDB Server手册中的 自然顺序 词汇表条目。

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() 方法接受以下参数:

  • $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": ...
}

要了解有关数组更新操作符的更多信息,请参阅 MongoDB Server手册中的 数组更新操作符 。

要查看演示如何使用 Laravel 集成更新文档的可运行代码示例,请参阅以下用法示例:

要学习;了解如何将文档插入MongoDB集合,请参阅插入文档指南。