【问题标题】:Update JSON nested values in Laravel Eloquent在 Laravel Eloquent 中更新 JSON 嵌套值
【发布时间】:2021-01-10 18:56:10
【问题描述】:

我需要使用 Laravel Eloquent 更新 JSON 的一些嵌套值,但没有得到我想要的优化结果。下面的json需要经常更新。我对此有一个可行的解决方案,但需要对解决方案进行微调。

{
  "a": {
    "b": 12,
    "c": 792,
    "d": 45,
    "e": {
      "1": {
        "name": "Guna",
        "city": "city1",
        "dob": 2000
      },
      "2": {
        "name": "Raj",
        "city": "city2",
        "dob": 2001
      },
      "3": {
        "name": "Dhamu",
        "city": "city3",
        "dob": 1985
      },
      "4": {
        "name": "Bhavi",
        "city": "city5",
        "dob": 1985
      }
    }
  }
}

尝试过的代码

$c_array=Json::decode($this->company->details, 1);
$c_array['a']['Player'][$p[0]]['st']=$p[1];
$c_array['a']['e'][1]['name'] = 'Bheem';
$c_array['a']['e'][1]['city'] = 'City10';
$c_array['a']['e'][2]['name'] = 'Dhanu';
$c_array['a']['e'][2]['city'] = 'City5';
$this->company()->update(['details' => Json::encode($c_array)]);

上面的代码工作正常,但是在检查查询时整个 json 都会更新。我只需要更新需要更新的单个键。

我们可以使用 Query Builder (DB::raw) 更新代码,如下所示,

update ultimate_squad set squad=JSON_SET(details,'$.a.e."1".name','Bheem','$.a.e."1".city','City10','$.a.e."2".name','Dhanu','$.a.e."2".city','City5') where c_id=1;

【问题讨论】:

  • 我在 Stack Overflow 上看到的关于在 MySQL 中使用 JSON 的每一个问题都可以得到回答,“如果你不使用 JSON,这将更容易和更有效。”
  • @BillKarwin 我有上述更新 JSON 值的解决方案,但需要微调
  • 是的,我明白了。你已经写了上面几乎相同的词。
  • 通过在 JSON 中实现复杂的数据模型而不是普通的行和列,您正在创建一个 Inner-Platform Effect:创建“一个可定制的系统,以成为一个副本,通常是一个糟糕的副本,他们正在使用的软件开发平台。”如果您希望它更精细,那么您必须做的第一件事就是停止使用 JSON。而是使用普通的行和列。
  • 您可能会说,“但它必须灵活。”好吧,你不能让它如此灵活同时优化。

标签: php mysql laravel eloquent mysql-json


【解决方案1】:

是的,如果使用 JSON 转换,您可以使用 Eloquent 更新单个属性:

class User extends Model
{
    protected $casts = [
        'options' => 'array',
    ];
}
$user = User::find(1);

$user->update(['options->enabled' => true]);

https://laravel.com/docs/8.x/eloquent-mutators#array-and-json-casting

如果你需要批量赋值,你也应该把它添加到可填充中

protected $fillable = [
    'options->enabled',
];

https://laravel.com/docs/8.x/eloquent#mass-assignment-json-columns

此外,您可以通过使用预定义类或创建您自己的自定义类来实现返回您自己的逻辑的Illuminate\Contracts\Database\Eloquent\Castable,为您的 JSON 字段创建更详细的解析。

use Illuminate\Database\Eloquent\Casts\AsArrayObject;

protected $casts = [
    'options' => AsArrayObject::class,
];

https://laravel.com/docs/8.x/eloquent-mutators#array-object-and-collection-casting

【讨论】:

    【解决方案2】:

    你可以在 mysql 中创建 temptable 并将整个 json 存储在那里 然后使用您想要的特定键运行更新查询。 阅读以下参考资料:

    Create a temporary table in a SELECT statement without a separate CREATE TABLE

    How to create TEMPORARY table in laravel

    【讨论】:

    • 显而易见的是我们已经有一张桌子了。这个答案不是问题的解决方案。
    猜你喜欢
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 2021-11-04
    • 2015-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多