You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel MongoDB中整数、浮点数及布尔字段存为字符串如何解决?

解决Laravel中MongoDB字段数据类型存储错误问题

问题概述

在Laravel项目中使用MongoDB时,age(整数)、height/weight(浮点数)、concluded(布尔值)字段被存储为带引号的字符串类型,而非预期的对应原生数据类型。

当前存储结果

{
  "_id": {
    "$oid": "64b41ba740f8fc543547b2d3"
  },
  "name": "Michael",
  "age": "20",
  "height": "1.89",
  "weight": "78.79",
  "begin": "2023-07-16",
  "finish": "2023-07-28",
  "concluded": "true",
  "updated_at": {
    "$date": "2023-07-16T16:33:22.423Z"
  },
  "created_at": {
    "$date": "2023-07-16T16:32:39.375Z"
  }
}

预期存储结果

{
  "_id": {
    "$oid": "64b41ba740f8fc543547b2d3"
  },
  "name": "Michael",
  "age": 20,
  "height": 1.89,
  "weight": 78.79,
  "begin": "2023-07-16",
  "finish": "2023-07-28",
  "concluded": true,
  "updated_at": {
    "$date": "2023-07-16T16:33:22.423Z"
  },
  "created_at": {
    "$date": "2023-07-16T16:32:39.375Z"
  }
}

相关代码文件

迁移文件 2023_07_08_114314_create_persons_table.php

public function up()
{
    Schema::create('persons', function (Blueprint $collection) {
        $collection->string('name');
        $collection->integer('age');
        $collection->double('height');
        $collection->double('weight');
        $collection->date('begin');
        $collection->date('finish');
        $collection->boolean('concluded')->default(false);
        $collection->timestamps();
        $collection->softDeletes();
    });
}

模型 PersonModel.php

class PersonModel extends Model
{
    use HasFactory, SoftDeletes;

    protected $connection = 'mongodb';

    protected $collection = 'persons';

    protected $primary_key = '_id';

    protected $fillable = [
        'name',
        'age',
        'height',
        'weight',
        'begin',
        'finish',
        'concluded',
    ];
}

控制器 PersonController.php

public function store(PersonRequest $request)
{
    PersonModel::create(array_map('trim', $request->validated()));

    Log::channel('daily')->info("$request->name was added in system.");

    return redirect('/')->with('success_store', "$request->name was added in system.");
}

解决方案

问题根源:HTTP请求传递的所有参数默认都是字符串类型,即便迁移文件定义了字段类型,Laravel MongoDB不会自动进行类型转换,需要显式指定字段的类型转换规则。

方案1:模型中添加$casts属性(推荐)

在PersonModel中添加$casts数组,明确指定每个字段的目标数据类型,Laravel会自动在存储和读取时完成类型转换:

class PersonModel extends Model
{
    use HasFactory, SoftDeletes;

    protected $connection = 'mongodb';

    protected $collection = 'persons';

    protected $primaryKey = '_id'; // 修正:Laravel规范为驼峰式$primaryKey,原属性名错误

    protected $fillable = [
        'name',
        'age',
        'height',
        'weight',
        'begin',
        'finish',
        'concluded',
    ];

    // 添加类型转换规则
    protected $casts = [
        'age' => 'integer',
        'height' => 'float',
        'weight' => 'float',
        'concluded' => 'boolean',
        'begin' => 'date',
        'finish' => 'date'
    ];
}

方案2:控制器中手动转换数据类型

在创建模型实例前,手动将字符串转换为对应数据类型:

public function store(PersonRequest $request)
{
    $data = array_map('trim', $request->validated());

    // 手动转换类型
    $data['age'] = (int)$data['age'];
    $data['height'] = (float)$data['height'];
    $data['weight'] = (float)$data['weight'];
    // 兼容字符串格式的布尔值转换
    $data['concluded'] = filter_var($data['concluded'], FILTER_VALIDATE_BOOLEAN);

    PersonModel::create($data);

    Log::channel('daily')->info("$request->name was added in system.");

    return redirect('/')->with('success_store', "$request->name was added in system.");
}

方案3:在请求验证类中转换类型

在PersonRequest类中添加prepareForValidation方法,在验证前完成类型转换:

class PersonRequest extends FormRequest
{
    // ... 其他规则方法

    protected function prepareForValidation()
    {
        $this->merge([
            'age' => (int)$this->age,
            'height' => (float)$this->height,
            'weight' => (float)$this->weight,
            'concluded' => filter_var($this->concluded, FILTER_VALIDATE_BOOLEAN),
        ]);
    }
}

注意:方案1是最简洁且符合Laravel最佳实践的方式,推荐优先使用。同时修正模型中的$primary_key为$primaryKey,避免潜在的主键识别问题。

内容的提问来源于stack exchange,提问作者user22236733

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:12:04