[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というテーブル

カラム名型説明_idstring一意のIDbodystring本文read_atdatetime既読時間created_atdatetime作成時間

源代码

模特儿

应用程序/模型/会话.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,所以如果我有任何新的发现,我会继续发布。

感谢您一直阅读到最后。

bannerAds