[Laravel, MongoDB] 在进行 MongoDB 更新操作时的注意事项
首先
在使用Laravel×MongoDB进行业务开发时,由于Laravel标准版本默认不支持MongoDB,我们使用了一个名为”laravel-mongodb”的库,用于将MongoDB以类似Eloquent的方式进行操作。
在这些中的一种情况下,当遇到与Eloquent有些不同的行为而感到困惑时,这是一份备忘录。
前提
環境は
-
- Laravel 8.0.17
- laravel-mongodb 3.8.4
ライブラリはインストール済みです
composer require jenssegers/mongodb
数据库 (Chinese translation for “database”)
今回mongoDBにあるテーブルはtalksというテーブル
源代码
模特儿
应用程序/模型/会话.php
<?php
namespace App\Models;
use Jenssegers\Mongodb\Eloquent\Model;
class Talk extends Model
{
/**
* コレクション名.
*
* @var string
*/
protected $collection = 'talks';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'body',
'read_at',
];
/**
* 保存時、取得時にMongoDateとCarbonの形式の変換を行うカラムの設定。
*
* @var array
*/
protected $dates = [
'read_at'
];
}
使用Jenssegers\Mongodb\Eloquent\Model来导入库,并进行扩展操作。
控制器
↓应用\控制器\聊天控制器.php
public function detail($id)
{
...
$talk = Talk::findOrFail($id);
$talk->whereNull('read_at')->update(['read_at' => now()]);
...
}
当转到对话的详细页面时,将未读对话的read_at字段填上日期时间(Carbon),将其标记为“已读状态”。
确认动作
希望静心思考
通过上述代码执行TalkController的detail动作。
我打算将Carbon的now()保存起来,所以我认为它会变成ISODate(<当前日期时间>)。
{
...
read_at: ISODate('2022-07-16T00:56:15.378Z'),
...
created_at: ISODate('2022-07-16T00:56:15.378Z')
}
实际行为
不过,实际情况是这样的。
{
...
read_at: {},
...
created_at: ISODate('2022-07-16T00:56:15.378Z')
}
有一个空的对象进来了。。。
调查结果
为了某种理由
我发现了一个关于在执行mongoDB的update()操作时出现这种行为的问题。
看起来save()在now()时能按照预期运行。
而且,根据问题中提到的行为,保存的对象似乎以日期的形式保存。虽然与我的行为有点不同,但暂时先忽略它。
解决办法
尽管行为有所不同,但由于有一个共同点:都使用了”Carbon”,我按照上述问题中提到的建议”使用UTCDateTime类”进行了修正,如下所示。
↓App\Controllers\TalkController.php 的内容请进行中文的复述。
public function detail($id)
{
$talk->whereNull('read_at')->update(['read_at' => new UTCDateTime(new DateTime)]);
}
因为我想要当前时间,所以我试着用DateTime类的实例作为参数。
验证再次执行详细操作时,可以确认该值已按预期更新为以下内容。
{
...
read_at: ISODate('2022-07-16T00:56:15.378Z'),
...
created_at: ISODate('2022-07-16T00:56:15.378Z')
}
太好了。 le.)
看到的事物
使用save()方法可以使用Carbon,为什么不能使用update()方法…这是一个意外的陷阱。
在使用MongoDB时,批量更新多个记录的特定字段(在本例中是talks的read_at字段)是相当常见的操作。所以我希望Carbon也能支持这种操作呢,这只是我的小小愿望而已,哈哈。
由于我刚刚开始接触MongoDB,所以如果我有任何新的发现,我会继续发布。
感谢您一直阅读到最后。